Запрос с агрегатом, поиском и конвейером в Mongodb - PullRequest
1 голос
/ 14 апреля 2020

Я должен управлять стеной с комментариями, у каждой стены есть много родительских комментариев, а у каждого родительского комментария есть дочерние комментарии.

моя коллекция стены похожа на

 groupId : {type: Schema.Types.ObjectId, ref: 'groups', unique: true},
    comments : [{
        commentId : {type: Schema.Types.ObjectId, ref: 'comments'},
        user : {type: Schema.Types.ObjectId, ref: 'users'},
    }],

и коллекция комментариев похожа на это

text : String,
parentCommentId : {type: Schema.Types.ObjectId, ref: 'comments', default : null},

Я хочу отобразить мою стену с помощью родительских комментариев, каждый дочерний комментарий под родительским комментарием.

i пробовал этот запрос, но он не дал результатов

db.getCollection('walls').aggregate([
        {$match: {groupId: ObjectId("5e8c5caa75b1cd342a1175eb")}},
        {
            "$lookup": {
                from: "comments",
                let: { item: "$comments.commentId" },
                pipeline: [
                    { $match:
                        { $expr: { $eq: [ "$parentCommentId",  "$$item" ] }


                        }
                    },
                    { $project: {
                        "_id": 1,
                        "parentCommentId": 1,
                        "text": 1                       
                    } }
                ],
                as: "comments"
            }
        },
        {
            $project: {
                groupId: 1,
                "comments":1,
                date: 1
            }
        }
    ])

данные в стенах

{
    "_id" : ObjectId("5e95b4b49d3e303d667a8b71"),
    "groupId" : ObjectId("5e8c5caa75b1cd342a1175eb"),
    "comments" : [ 
        {
            "_id" : ObjectId("5e95b4b49d3e303d667a8b72"),
            "commentId" : ObjectId("5e95b4b49d3e303d667a8b70")
        }, 
        {
            "_id" : ObjectId("5e95b4ef80ae1244693aa857"),
            "commentId" : ObjectId("5e95b4ef80ae1244693aa856")
        }, 
        {
            "_id" : ObjectId("5e95b51080ae1244693aa859"),
            "commentId" : ObjectId("5e95b51080ae1244693aa858")
        }, 
        {
            "_id" : ObjectId("5e95b51d80ae1244693aa85b"),
            "commentId" : ObjectId("5e95b51d80ae1244693aa85a")
        },
        {
           "_id" : ObjectId("5e95b53580ae1244693aa85e"),
           "commentId" : ObjectId("5e95b53580ae1244693aa85c")
        }
    ],

}

данные в комментариях

{
    "_id" : ObjectId("5e95b4b49d3e303d667a8b70"),
    "parentCommentId" : null,
    "text" : "Hello parent 1"
}

{
    "_id" : ObjectId("5e95b4ef80ae1244693aa856"),
    "parentCommentId" : null,
    "text" : "Hello parent 2",
    "date" : ISODate("2020-04-14T13:04:47.860Z")
}

{
    "_id" : ObjectId("5e95b51080ae1244693aa858"),
    "parentCommentId" : ObjectId("5e95b4b49d3e303d667a8b70"),
    "text" : "Hello child 1 parent 1"
}

{
    "_id" : ObjectId("5e95b51d80ae1244693aa85a"),
    "parentCommentId" : ObjectId("5e95b4b49d3e303d667a8b70"),
    "text" : "Hello child 2 parent 1"

}

{
    "_id": "5e95b53580ae1244693aa85c",
    "parentCommentId": "5e95b4ef80ae1244693aa856",
    "text": "Hello child 1 parent 2",
}

желаемый результат

{
    "success": true,
    "data": [
        {
            "_id": "5e95b4b49d3e303d667a8b71",
            "groupId": "5e8c5caa75b1cd342a1175eb",
            "comments": [
                {
                    "_id": "5e95b4b49d3e303d667a8b70",
                    "parentCommentId": null,
                    "text": "Hello parent 1",
                    "childs": {
                                 {
                                   "_id": "5e95b51080ae1244693aa858",
                                   "parentCommentId": "5e95b4b49d3e303d667a8b70",
                                   "text": "Hello child 1 parent 1",
                                 },
                                 {
                                   "_id": "5e95b51d80ae1244693aa85a",
                                   "parentCommentId": "5e95b4b49d3e303d667a8b70",
                                   "text": "Hello child 2 parent 1",
                                 },
                              }
                },
                {
                    "_id": "5e95b4ef80ae1244693aa856",
                    "parentCommentId": null,
                    "text": "Hello parent 2",
                    "childs": {
                                  {
                                    "_id": "5e95b53580ae1244693aa85c",
                                    "parentCommentId": "5e95b4ef80ae1244693aa856",
                                    "text": "Hello child 1 parent 2",
                                 }
                         }
                },


            ],
         }
    ]
}

Как я могу изменить свой запрос? спасибо.

1 Ответ

0 голосов
/ 14 апреля 2020

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

db.walls.aggregate([
  { "$lookup": {
    "from": "comments",
    "let": { "commentIds": "$comments.commentId" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": ["$_id", "$$commentIds"] },
        "parentCommentId": null
      }},
      { "$sort": { "text": -1 }},
      { "$graphLookup": {
        "from": "comments",
        "startWith": "$_id",
        "connectFromField": "parentCommentId",
        "connectToField": "parentCommentId",
        "as": "childs"
      }}
    ],
    "as": "comments"
  }}
])

MongoPlayground

...