Mongodb子文档数组查找到子文档数组
我是刚到mongo的。我有以下收藏 文件: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,
{
"_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"
]
}
}
}
]
}
}
}
}
}
])