我使用$ lookup组合两个集合,我可以在'加入'集合上应用过滤器并在起始集合上使用投影,但我没有设法在连接上结合过滤器和投影使用$ redact和$ project尝试几种方法的集合。我已经密切关注stackoverflow,但我找不到这个组合。 这是一个例子: 集合元:
{ "Exp": "A","test": "OK","date": "3"}
{ "Exp": "B","test": "OK","date": "5"}
{ "Exp": "C","test": "Failed","date": "9"}
集合合并(待加入):
{ "Exp": "A","M1": "2","M2": "test","T": "1"}
{ "Exp": "A","M1": "2","M2": "val", "T": "2"}
{ "Exp": "A","M1": "2", "M2": "val","T": "3"}
{ "Exp": "B","M1": "1", "M2": "test","M4": "1","T": "1"}
{ "Exp": "B","M1": "1","M2": "val","M4": "1","T": "2"}
{ "Exp": "B","M1": "1","M2": "val","M4": "1","T": "3"}
{ "Exp": "C","M1": "2","M2": "test","M3": "2","T": "1"}
{ "Exp": "C","M1": "2","M2": "val","M3": "2","T": "2"}
{ "Exp": "C","M1": "2","M2": "val","M3": "2","T": "3"}
查询是:使用'Exp'加入'meta'和'merge',只选择meta.test =“OK”和merge.M2 =“val”的那些,但只显示meta.Exp,meta .test和merge.M1,merge.M2和merge.T。
这是我走了多远:
db.meta.aggregate([
{ $match: { test: "OK" }},
{ $lookup:
{ from: "merge",
localField: "Exp",
foreignField: "Exp",
as: "kin"
}
},
{ $project:
{ "Exp": true,
"test": true,
kin :
{ $filter:
{ input: "$kin",
as: "kin",
cond: { $eq: [ "$$kin.M2", "val" ]}
}
}
}
}
])
但是尝试在merge.M1,merge.M2和merge.T以及过滤器上包含一个额外的投影会一直失败。结果应该是:
{ "Exp" : "B",
"test" : "OK",
"kin" : [
{ "M1" : "1",
"M2" : "val",
"T" : "2"},
{ "M1" : "1",
"M2" : "val",
"T" : "3"}]
}
{ "Exp" : "A",
"test" : "OK",
"kin" : [
{ "M1" : "2",
"M2" : "val",
"T" : "2"},
{ "M1" : "2",
"M2" : "val",
"T" : "3"}
]
}
感谢您的提示! Jordi
答案 0 :(得分:0)
使用$map
指定要返回的数组的字段:
db.meta.aggregate([
{ "$match": { test: "OK" }},
{ "$lookup":{
"from": "merge",
"localField": "Exp",
"foreignField": "Exp",
"as": "kin"
}},
{ "$project": {
"Exp": 1,
"test": 1,
"kin": {
"$map": {
"input": {
"$filter": {
"input": "$kin",
"as": "k",
"cond": { "$eq": [ "$$k.M2", "val" ] }
}
},
"as": "k",
"in": {
"M1": "$$k.M1",
"M2": "$$k.M2",
"T": "$$k.T"
}
}
}
}}
])
为您返回:
/* 1 */
{
"_id" : ObjectId("5979a8857dcd6a5f6a9b4b9a"),
"Exp" : "A",
"test" : "OK",
"kin" : [
{
"M1" : "2",
"M2" : "val",
"T" : "2"
},
{
"M1" : "2",
"M2" : "val",
"T" : "3"
}
]
}
/* 2 */
{
"_id" : ObjectId("5979a8857dcd6a5f6a9b4b9b"),
"Exp" : "B",
"test" : "OK",
"kin" : [
{
"M1" : "1",
"M2" : "val",
"T" : "2"
},
{
"M1" : "1",
"M2" : "val",
"T" : "3"
}
]
}
答案 1 :(得分:0)
另一种方法,由colleaque提出使用第二个$投影。我认为这比$ map更有效,因为它不会遍历数组的每个元素。诀窍是重复第一个$投影的预测。
db.meta.aggregate([
{ $match: { test: "OK" }},
{ $lookup: { from: "merge", localField: "Exp", foreignField: "Exp", as:
"kin" }},
{ $project:
{ "Exp": true, "test": true, "date": true,
kin : { $filter: { input: "$kin", as: "kin", cond: { $eq: [
"$$kin.M2",
"val" ]}}
}
}
},
{ $project: {
"Exp": true, "test": true, "date": true,
"kin.M1": true, "kin.M2": true, "kin.T": true }
}
])