2016-11-24 1 views
1

У меня есть коллекция болтает с участниками поддокументом как так ..эквивалента группы захвата для согласованного поддокументе

{ 
    _id: '1', 
    participants: [ { _id: 'A', seen: false }, { _id: 'B', seen: false } ], 
    messages: [] 
} 

Есть только 2 участников и один из них являются CurrentUser. Я не знаю, что. Кроме того, существует только один чат для любой пары пользователей.

Для того, чтобы найти чат, я использую оба идентификатора пользователя. Таким образом, находка запрос выглядит следующим образом:

Chats.find( 
    { $and: [ 
     { participants: {$elemMatch: {_id: otherUserId}}}, 
     { participants: {$elemMatch: {_id: currentUserId}}} 
    ]} 
) 

Я хотел бы, чтобы позволить CurrentUser обновить свое seen поле в одной операции обновления.

В настоящее время я должен сначала найти чат, определить, какой индекс этих двух пользователей является currentUser, а затем создать документ для обновления этого пользователя и обновить его в отдельной операции.

Есть ли что-то похожее на группу захвата регулярных выражений, поэтому я могу узнать идентификатор элемента, который соответствует currentUserId? Возможно, это так .....

Chats.update( { $and: [ 
     { participants: {$elemMatch: {_id: otherUserId}}}, 
     { participants: capture({$elemMatch: {_id: currentUserId}})} 
    ]}, 
    { 
     $set: {"participants.(capture[0]).seen": true} 
    }) 

Или есть лучший способ?

ответ

3

Ну, это не может быть решение, которое вы ищете, но я подумал, что должен посоветовать на случай, если это поможет.

Chats.update( { $and: [ 
    { participants: {$elemMatch: {_id: otherUserId}}}, 
    { participants: {$elemMatch: {_id: currentUserId}}} 
]}, 
{ 
    $set: {"participants.$.seen": true} 
}) 

Это будет работать для вас, потому что $ elemMatch хранит индекс совпадающего массива. Когда вы будете использовать $ eleMatch, он сохранит индекс, сопоставляемый последним $ eleMatch, который будет вашим текущим пользователем. Итак, когда вы используете позиционный оператор, он обновит видимое поле для текущего пользователя.

+0

Это замечательно - немного странно, но оно работает! Я написал тесты, и они передаются в обоих случаях: ли currentUser хранится в 0 или 1. –

+0

Это интересный подход и работает без '$ elemMatch'. У вас есть ссылка на документы о том, как оператор '$ and' влияет на« $ -проекцию »? – JeremyK

+0

жаль, что нет. Это был след и ошибка. Хотелось бы, чтобы у меня было что-то, что можно было поддержать, и это было причиной того, что я не хотел, чтобы это было ответом. – Veeram

1

Простой способ легко обновить «видел» статус будет структурировать данные, как это:

{ 
    _id: '1', 
    participants: [ 'A', 'B'], 
    seen: [], 
    messages: [] 

}

Затем вы можете обновить «A» видел сообщение, как это :

Chats.update(
    { $and: [ {participants: 'A'}, {participants: 'B'} ] }, 
    { $addToSet: { seen: 'A' } } 
) 
  • $elemMatch не требуется, если у вас есть только один запрос состояние внутри него
  • $addToSet добавит только «А», если он не уже существует.
+0

Это аккуратно. И, когда новое сообщение прибывает из «B», я просто вытаскиваю «A» из увиденного? Спасибо за отзыв о $ elemMatch. Я читал это где-то, но вычислял $ и делал его достаточно сложным, чтобы потребоваться длинная версия. Извините, я могу принять только один ответ. –

+0

Интересно, когда я опускаю $ elemMatch, позиционная нотация $ больше не работает, как описано в ответе @ Veeram. Однако find() все еще работает. –

+1

'Chats.update ({$ and: [{'members._id': 'B'}, {'members._id': 'A'}]}, {$ set: {" участники. $. Seen ": true}}) 'Это задает атрибуту« A »видимое свойство true. – JeremyK

Смежные вопросы