Посмотрите, содержит ли вложенный массив объектов значение | MongoDB

#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 для обработки ваших массивов слой за слоем.

  1. Вы можете сначала $map прокомментировать, чтобы спроектировать логическое значение, если пользователю нравится лайк1
  2. Затем вы можете использовать $anyElementTrue для выполнения проверки на проецируемом логическом

Вот игровая площадка Mongo, чтобы показать эту идею(с некоторыми незначительными изменениями в вашем примере). Вы можете изменить его в соответствии с вашими потребностями.

Комментарии:

1. Это прекрасно. Раньше $map я мало чем пользовался, так что спасибо тебе за это и за то, что ты привнес в мою жизнь игровую площадку Mongo.

2. К вашему сведению, я немного поиграл с ним, чтобы избежать второй проекции: Игровая площадка Mongo

3. @bourkison ваш новый код чище. Причина, по которой я разделил код на 2 этапа, заключается в демонстрационных целях, чтобы вы могли запускать этапы отдельно для лучшего понимания. Я бы посоветовал вам дополнить вашу новую версию в вашем вопросе, чтобы помочь большему количеству людей 🙂