Поиск только в том случае, если внешнее поле не является нулевым в mongoDB - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть сборники для статей и комментариев.Комментарий может иметь articleId (это ответ на статью) или parentId (это ответ на другой комментарий).Есть только 2 уровня, ответ на другой комментарий не может иметь ответ.

// articles
{ "_id": 100, "text": "Article text" } 

// comments
{ "_id": 1, "text": "First text", "articleId": 100 },
{ "_id": 2: "text": "Second text", "articleId": 100 },
{ "_id": 3, "text": "Third text", "parentId": 2 }  

Я хотел бы найти все статьи , комментарии статей и ответы к комментариям.

db.getCollection("articles").aggregate([
    { "$match": {} },

    // Lookup comments of article.
    { "$lookup": { "from": "comments", "localField": "_id", "foreignField": "parentId", as: "comments" } },
    { "$unwind": { "path": "$comments", "preserveNullAndEmptyArrays": true } },

    // Lookup answers to comments. There I need lookup only when foreignField is not null.
    { "$lookup": { "from": "comments", "localField": "comments._id", "foreignField": "parentId", "as": "comments.answers" } },
    { "$group": { "_id": "$_id", "comments": { "$push": "$comments" }, "text": { "first": "$text" } }
])

Работает, если в статье есть комментарии.Но если нет, то после первой lookup (комментарии статьи) статья выглядит так (пустой массив в порядке):

{ "_id": 100, "text": "Article text", "comments": [] }

А после второй lookup (ответы на комментарии):

{
    "_id": 100,
    "text": "Article text",
    "comments": [{
        "answers": [
            { "_id": 1, "text": "First text", "articleId": 100 },
            { "_id": 2: "text": "Second text", "articleId": 100 }
        ]
    }]
}

Даже если нет комментариев, есть некоторые ответы на комментарии.Я думаю, это потому, что localField comments._id равен null, а ForeignField parentId из этих ответов также null.Есть ли способ поиска только тогда, когда foreignField равен not null?

1 Ответ

0 голосов
/ 17 февраля 2019

Вы можете использовать агрегацию ниже с mongodb 3.6 и выше

Article.aggregate([
  { "$lookup": {
    "from": "comments",
    "let": { "articleId": "$_id" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": [ "$articleId", "$$articleId" ] } } },
      { "$lookup": {
        "from": "comments",
        "let": { "commentId": "$_id" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$parentId", "$$commentId" ] } } }
        ],
        "as": "answers"
      }}
    ],
    "as": "comments"
  }}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...