#mongodb #mongoose #mongodb-query #aggregation-framework
Вопрос:
У меня есть коллекция posts
, в которой есть массив объектов comments
. Внутри этого массива объектов у меня есть еще один массив объектов likes
.
Я пытаюсь написать запрос, который извлекает последние 5 комментариев из сообщения и извлекает только true
или false
для likes
, основываясь на том, понравился ли уже комментарий пользователю.
Я уже писал это до сих пор:
db.posts.aggregate([
{
"$match": {
"_id": postId
}
},
{
"$project":
{
"comments": {
"$slice": [ "$comments", -5 ]
}
}
},
{
"$project": {
"comments.content": 1,
"comments.likes": {
"$eq": [ "comments.likes.$.createdBy.username", username ]
}
}
}
])
Но это, кажется, тянет false
каждый раз.
Можно ли это сделать без необходимости писать отдельный запрос, чтобы проверить, понравилось ли пользователю?
ИЗМЕНИТЬ: Итак, для приведенного ниже документа:
С username = "testusername"
, и postId = "60fcd335abbe5a73583b69f0"
Я бы ожидал выхода:
[
{
"content": "test comment",
"likes": true
},
{
"content": "another test comment",
"likes": true
}
]
И с username = "testusername2"
я бы ожидал результата
[
{
"content": "test comment",
"likes": true
},
{
"content": "another test comment",
"likes": false
}
]
Ответ
Спасибо @ray за вашу помощь в этом. Сжатый код Здесь, хотя, пожалуйста, смотрите ответ Рэя, чтобы код был разделен с объяснением.
Комментарии:
1. было бы полезно, если бы вы могли предоставить примеры данных и ожидаемые результаты для всех присутствующих здесь, чтобы взглянуть
2. еще один совет: вставьте код/образец данных в текст вместо изображения; Другим было бы проще скопировать и скопировать его
Ответ №1:
Вы можете использовать $map
для обработки ваших массивов слой за слоем.
- Вы можете сначала
$map
прокомментировать, чтобы спроектировать логическое значение, если пользователю нравится лайк1 - Затем вы можете использовать
$anyElementTrue
для выполнения проверки на проецируемом логическом
Вот игровая площадка Mongo, чтобы показать эту идею(с некоторыми незначительными изменениями в вашем примере). Вы можете изменить его в соответствии с вашими потребностями.
Комментарии:
1. Это прекрасно. Раньше
$map
я мало чем пользовался, так что спасибо тебе за это и за то, что ты привнес в мою жизнь игровую площадку Mongo.2. К вашему сведению, я немного поиграл с ним, чтобы избежать второй проекции: Игровая площадка Mongo
3. @bourkison ваш новый код чище. Причина, по которой я разделил код на 2 этапа, заключается в демонстрационных целях, чтобы вы могли запускать этапы отдельно для лучшего понимания. Я бы посоветовал вам дополнить вашу новую версию в вашем вопросе, чтобы помочь большему количеству людей 🙂