Mic*_*hal 7 mongodb aggregation-framework
我收集了文章和评论。评论可能有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 }
Run Code Online (Sandbox Code Playgroud)
我想找到所有文章、文章评论和评论答案。
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" } }
])
Run Code Online (Sandbox Code Playgroud)
如果文章有一些评论,它就会起作用。但如果没有,在第一篇lookup(文章评论)文章之后看起来像这样(空数组就可以了):
{ "_id": 100, "text": "Article text", "comments": [] }
Run Code Online (Sandbox Code Playgroud)
第二次之后lookup(评论的答案):
{
"_id": 100,
"text": "Article text",
"comments": [{
"answers": [
{ "_id": 1, "text": "First text", "articleId": 100 },
{ "_id": 2: "text": "Second text", "articleId": 100 }
]
}]
}
Run Code Online (Sandbox Code Playgroud)
即使没有评论,评论也有一些回复。我认为这是因为这些答案的 localFieldcomments._id是null和foreignFieldparentId也是null。有没有办法只在foreignField为时查找not null?
您可以在 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"
}}
])
Run Code Online (Sandbox Code Playgroud)