Match Two different fields in Mongoose, Aggregate?

女生的网名这么多〃 提交于 2021-01-28 06:40:19

问题


I'm trying to match two different fields in the same document. But didn't get expected output as I want. Let me show with an example.

I want to match weighted.phaseId with phases._id in same documents and not match should be removed from phases fields.

Does any one have an Idea ?

// Document after processing some aggregate query over a database.

{
    "_id" : ObjectId("5a680c803096130f93d11c7a"),
    "weighted" : [ 
        {
            "phaseId" : ObjectId("5a6734c32414e15d0c2920f0"),
            "_id" : ObjectId("5a680c803096130f93d11c7b")
        },
        {
            "phaseId" : ObjectId("5a6734c32414e15d0c2920ee"),
            "_id" : ObjectId("5a680c803096130f93d11c7c")
        }
    ],
    "phases" : [ 
        {
            "phase_name" : "Phase 1",
            "_id" : ObjectId("5a6734c32414e15d0c2920f0")
        }, 
        {
            "phase_name" : "Phase 2",
            "_id" : ObjectId("5a6734c32414e15d0c2920ef")
        }, 
        {
            "phase_name" : "Phase 3",
            "_id" : ObjectId("5a6734c32414e15d0c2920ee")
        }, 
        {
            "phase_name" : "Phase 4",
            "_id" : ObjectId("5a6734c32414e15d0c2920ed")
        }
    ]
}

// Expected Output

{
    "_id" : ObjectId("5a680c803096130f93d11c7a"),
    "weighted" : [ 
        {
            "phaseId" : ObjectId("5a6734c32414e15d0c2920f0"),
            "_id" : ObjectId("5a680c803096130f93d11c7b")
        },
        {
            "phaseId" : ObjectId("5a6734c32414e15d0c2920ee"),
            "_id" : ObjectId("5a680c803096130f93d11c7c")
        }
    ],
    "phases" : [ 
        {
            "phase_name" : "Phase 1",
            "_id" : ObjectId("5a6734c32414e15d0c2920f0")
        },
        {
            "phase_name" : "Phase 3",
            "_id" : ObjectId("5a6734c32414e15d0c2920ee")
        }
    ]
}

回答1:


You can use following aggregation:

db.col.aggregate([
    {
        $addFields: {
            weightedIds: {
              $map:
                 {
                   input: "$weighted",
                   as: "w",
                   in: "$$w.phaseId"
                 }
            }
        }
    },
    {
      $project: {
        _id: 1,
        weighted: 1,
        phases: {
            $filter: {
             input: "$phases",
             as: "phase",
             cond: { $gte: [ { $indexOfArray: [ "$weightedIds" , "$$phase._id" ] }, 0 ] }
            }
        }
      }
    }
])

We're using $map to take only phaseId field of weighted and then we can filter out phases using $filter checking for each phase whether corresponding id exists (using $indexOfArray which returns -1 otherwise)



来源:https://stackoverflow.com/questions/48556504/match-two-different-fields-in-mongoose-aggregate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!