Как получить условный агрегатный поиск по внешнему ключу - PullRequest
1 голос
/ 01 мая 2019

После многих попыток у меня не получится хорошей условной агрегации моих коллекций.

Я использую две коллекции:

рас , которые имеют коллекцию рецензий .

Мне нужно получить для моего второго конвейера только опубликованные рецензии .Я не хочу использовать $project.Можно ли использовать только $match?Когда я использую localField, foreignField, он работает отлично, но мне нужно фильтровать только опубликованные обзоры.Я так много боролся с этим, я не понимаю, почему let не дает мне иностранный ключ.Я пробовал: _id, $reviews и т. Д.

Мой $lookup выглядит следующим образом:

{
    $lookup: {
      from: "reviews",
      as: "reviews",
      let: { reviewsId: "$_id" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                // If I comment the next line, it give all the reviews to all the races
                { $eq: ["$_id", "$$reviewsId"] },
                { $eq: ["$is_published", true] }
              ]
            }
          }
        }
      ]

      // localField: "reviews",
      // foreignField: "_id"
    }
  },

Пример гонки :

{  
   "description":"Nice race",
   "attendees":[  

   ],
   "reviews":[  
      {  
         "$oid":"5c363ddcfdab6f1d822d7761"
      },
      {  
         "$oid":"5cbc835926fa61bd4349a02a"
      }
   ],
   ...
}

Пример обзора :

{  
   "_id":"5c3630ac5d00d1dc26273dab",
   "user_id":"5be89576a38d2b260bfc1bfe",
   "user_pseudo":"gracias",
   "is_published":true,
   "likes":[],
   "title":"Best race",
   "__v":10,
   ...
}

Я скоро сойду с ума: '(... Как этого добиться?

Ответы [ 2 ]

1 голос
/ 01 мая 2019

Сначала вы должны принять правильное поле, чтобы получить данные из ссылочной коллекции, т.е. reviews.И во-вторых, вам нужно использовать $in оператор агрегирования, поскольку ваше поле reviews является массивом ObjectId с.

db.getCollection('races').aggregate([
  { "$lookup": {
    "from": "reviews",
    "let": { "reviews": "$reviews" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": [ "$_id", "$$reviews" ] },
        "is_published": true
      }}
    ],
    "as": "reviews"
  }}
])
1 голос
/ 01 мая 2019

Ваша проблема в этой строке:

        { $eq: ["$is_published", true] }

Вы используете этот документ _id поле для соответствия с отзывами.

Правильная версия выглядит следующим образом:

(

    [
        { 
            "$unwind" : "$reviews"
        }, 
        { 
            "$lookup" : {
                "from" : "reviews", 
                "as" : "reviews", 
                "let" : {
                    "reviewsId" : "$reviews"
                }, 
                "pipeline" : [
                    {
                        "$match" : {
                            "$expr" : {
                                "$and" : [
                                    {
                                        "$eq" : [
                                            "$_id", 
                                            "$$reviewsId"
                                        ]
                                    },
                                     { $eq: ["$is_published", true] }
                                ]
                            }
                        }
                    }
                ]
            }
        }
    ], 
);

и теперь, если вы хотите восстановить старую структуру, добавьте:

{
  $group: {
           _id: "$_id",
           reviews: {$push: "$reviews"},
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...