匹配Mongoose,Aggregate中的两个不同字段?

时间:2018-02-01 06:20:08

标签: node.js mongodb mongoose aggregate

我试图匹配同一文档中的两个不同字段。但是我没有按照自己的意愿获得预期的输出。 让我举一个例子。

我想在同一文档中将weighted.phaseIdphases._id匹配,并且应从phases字段中删除不匹配。

有人有想法吗?

//在数据库上处理一些聚合查询后的文档。

{
    "_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")
        }
    ]
}

//预期输出

{
    "_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 个答案:

答案 0 :(得分:1)

您可以使用以下聚合:

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 ] }
            }
        }
      }
    }
])

我们正在使用$map仅使用phaseId weighted字段,然后我们可以使用$filter检查每个阶段来过滤掉phases是否存在相应的id(使用$indexOfArray,否则返回-1)