Mongodb子文档数组查找到子文档数组

Mongodb子文档数组查找到子文档数组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我是刚到mongo的。我有以下收藏 文件: { "_id" : ObjectId("5eb256c9e519051af2eeb5f7"), "name" : "Income", "types" : [ { "typeId" : ObjectId("5eb257a3e519051af2eeb624"), "name" : "W2", "tenantId" : null,

我是刚到mongo的。我有以下收藏

文件:

{
    "_id" : ObjectId("5eb256c9e519051af2eeb5f7"),
    "name" : "Income",
    "types" : [ 
        {
            "typeId" : ObjectId("5eb257a3e519051af2eeb624"),
            "name" : "W2",
            "tenantId" : null,
            "message" : "",
            "createdOn" : null,
            "createdBy" : 1.0,
            "isActive" : true
        }, 
        {
            "typeId" : ObjectId("5eb257a3e519051af2eeb639"),
            "name" : "Salary Slip",
            "tenantId" : 1,
            "message" : "",
            "createdOn" : null,
            "createdBy" : 1.0,
            "isActive" : true
        }
    ]
}
请求:

{
    "_id" : ObjectId("5eb25d1fe519051af2eeb72d"),
    "employeeId" : 1234,
    "customerId" : 1275,
    "tenantId" : 1,
    "createdOn" : ISODate("2013-10-01T00:00:00.000Z"),
    "loanApplicationId" : 1.0,
    "status" : "requested",
    "message" : "Dear John, please send following documents.",
    "documents" : [ 
        {
            "typeId" : null,
            "displayName" : "W2 2016",
            "message" : "please upload salary slip for year 2016",
            "status" : "requested",
            "files" : []
        }, 
        {
            "typeId" : ObjectId("5eb257a3e519051af2eeb624"),
            "displayName" : "W2 2016",
            "message" : "please upload salary slip for year 2016",
            "status" : "requested",
            "files" : []
        }
    ]
}
文档集合中的typeId是文档类型的id,其中请求中的typeId是可以为空的外部字段。如何获得以下输出

{
    "_id" : ObjectId("5eb25d1fe519051af2eeb72d"),
    "employeeId" : 1234,
    "customerId" : 1275,
    "tenantId" : 1,
    "createdOn" : ISODate("2013-10-01T00:00:00.000Z"),
    "loanApplicationId" : 1.0,
    "status" : "requested",
    "message" : "Dear John, please send following documents.",
    "documents" : [ 
        {
            "typeId" : null,
            "typeInfo": null,
            "displayName" : "W2 2016",
            "message" : "please upload salary slip for year 2016",
            "status" : "requested",
            "files" : []
        }, 
        {
            "typeId" : ObjectId("5eb257a3e519051af2eeb624"),
            "typeInfo": {
            "name": "W2" 
            },
            "displayName" : "W2 2016",
            "message" : "please upload salary slip for year 2016",
            "status" : "requested",
            "files" : []
        }
    ]
}

我喜欢解决这个问题,这是一个棘手、漫长而复杂的过程。嗯,我也是初学者,所以我用了所有的基本概念。您可以尝试以下代码:

db.request.aggregate([
{
$展开:“$文档”
},
{
$lookup:{
从:“文件”,
让我们:{
请求类型ID:“$documents.typeId”
},
管道:[
{
$展开:“$类型”
},
{
$match:{
$expr:{
$eq:[
“$$req_typeId”,
“$types.typeId”
]
}
}
}
],
as:“文档.示例”
}
},
{
$REWIND:{
路径:“$documents.example”,
preserveNullAndEmptyArrays:true
}
},
{
$group:{
_id:“$\u id”,
雇员ID:{
$first:“$employeeId”
},
客户ID:{
$first:“$customerId”
},
租户:{
$first:“$TENATID”
},
createdOn:{
$first:“$createdOn”
},
贷款应用程序ID:{
$first:“$LOANpplicationId”
},
地位:{
$first:“$status”
},
信息:{
$first:“$message”
},
文件:{
$push:{
typeId:“$documents.typeId”,
类型信息:{
$cond:[
{
$eq:[
“$documents.example”,
未定义
]
},
无效的
{
名称:“$documents.example.types.name”
}
]
},
displayName:“$documents.displayName”,
消息:“$documents.message”,
状态:“$documents.status”,
文件:“$documents.files”
}
}
}
}
])
如果您在任何时候陷入困境,我已经提供了,在这里您可以在聚合管道的一个阶段一个阶段地执行查询,否则请联系我。这是一个很长的问题,需要时间去理解。同时,我会尽量缩小它。如果我得到什么,我会在这里更新

编辑:


我将查询缩短了近50%(以行为单位)。这是我以前的方法

使用默认的
$lookup
语法,您可以使用原子/数组值联接,并将结果存储在
tmp
变量中。在下一步中,我们迭代
documents
字段,并在
tmp
中找到具有相同
typeId
的变量项

注意:如果您需要的字段多于
name
,只需更改为
{typeInfo:$$this}

试试这个:

db.Requests.aggregate([
  {
    $lookup: {
      from: "Documents",
      localField: "documents.typeId",
      foreignField: "types.typeId",
      as: "tmp"
    }
  },
  {
    $addFields: {
      tmp: "$$REMOVE",
      documents: {
        $map: {
          input: "$documents",
          as: "doc",
          in: {
            $mergeObjects: [
              "$$doc",
              {
                $reduce: {
                  input: {
                    $reduce: {
                      input: "$tmp.types",
                      initialValue: [],
                      in: {
                        $concatArrays: [
                          "$$value",
                          "$$this"
                        ]
                      }
                    }
                  },
                  initialValue: {},
                  in: {
                    $cond: [
                      {
                        $eq: [
                          "$$this.typeId",
                          "$$doc.typeId"
                        ]
                      },
                      {
                        typeInfo: {
                          name: "$$this.name"
                        }
                      },
                      "$$value"
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])