mongodb | Как обновить (найти и изменить) после агрегата
Я хочу обновить некоторые значения в соответствии с результатом после выполнения запроса.
Что я хочу +1 к значению "comment_sort", если условие истинно.
Условие: если "comment_group" равен 1, а "comment_sort" больше 0
Исходная база данных является..
{
"_id" : ObjectId("5bc984ef8e798ccb0309ef13"),
"post_no" : 56,
"username" : "a@a.aa",
"nickname" : "nickNameSuccess",
"post_content" : "56",
"post_title" : "56"
"comment" : [
{
"comment_no" : 238,
"comment_sort" : 1, // (+1) "comment_sort" : 2
"comment_depth" : 0,
"comment_group" : 1
},
{
"comment_no" : 240,
"comment_sort" : 2, // (+1) "comment_sort" : 3
"comment_depth" : 1,
"comment_group" : 1
},
{
"comment_no" : 235,
"comment_sort" : 1,
"comment_depth" : 0,
"comment_group" : 2
},
{
"comment_no" : 237,
"comment_sort" : 2,
"comment_depth" : 0,
"comment_group" : 2
}
]
}
Запрос это..
db.getCollection('post').aggregate([
{"$match" : {"post_no": 56}},
{ "$project": {
"comment": {
"$map": {
"input": "$comment",
"in": {
"comment_no": "$$this.comment_no",
"comment_group": "$$this.comment_group",
"comment_sort": "$$this.comment_sort",
"comment_depth": "$$this.comment_depth"
}
}
}
}},
{ "$unwind": '$comment' },
{"$match" : {"comment.comment_group": 1}},
{"$match" : {"comment.comment_sort": {"$gt":0}} },
// { $group: { _id: null, comment_sort: { $max: "$comment.comment_sort" }}}
])
Результат..
{
"_id" : ObjectId("5bc984ef8e798ccb0309ef13"),
"comment" : {
"comment_no" : 238,
"comment_group" : 1,
"comment_sort" : 1,
"comment_depth" : 0
}
},
{
"_id" : ObjectId("5bc984ef8e798ccb0309ef13"),
"comment" : {
"comment_no" : 240,
"comment_group" : 1,
"comment_sort" : 2,
"comment_depth" : 1
}
}
Исходя из этого, я хочу увеличить (+1) только значение 'comment_sort'.
(напр. 1 -> 2, 2 -> 3)
Как я могу улучшить запрос?
Я хотел бы совет.
С уважением.
1 ответ
Вы не можете обновить свои документы из конвейера агрегации (этап $out заменит всю вашу коллекцию). Однако вы можете преобразовать свою агрегацию в запрос на обновление с помощью позиционных фильтров, чтобы обновить соответствующий элемент вашего массива. Вот запрос:
db.getCollection('post').update(
{post_no:56},
{$inc:{"comment.$[com].comment_sort":1}},
{arrayFilters: [ {$and:[{"com.comment_group": 1},{"com.comment_sort": {"$gt":0}} ]}] }
)
Пояснения:
- Первый документ соответствует вашей первой стадии матча.
- Второй документ - это обновление, которое необходимо выполнить. $[com] является идентификатором для опции arrayFilters.
- Третий документ - это документ параметров, содержащий фильтры для сопоставления элементов массива arrayFilters. Один идентификатор должен иметь один соответствующий arrayFilter, поэтому используйте $ и для фильтров. Комбинированный фильтр соответствует вашим 2 последним стадиям матча.
Надеюсь, поможет.
РЕДАКТИРОВАТЬ Разматывание не выполняется во время обновления, поэтому в результате запроса будет отображаться 1 обновленный документ. Но 2 элемента массива будут увеличены. (В этом случае конечно)