我已更新到Mongodb 2.6.1并尝试使用新的$redact聚合功能来解决业务问题,但未成功。我遇到的所有$ redact示例都针对外部变量或静态值进行评估。
我需要根据兄弟子文档中的值消除一些生成的文档。如果可能的话,我相信$ redact将是这样做的方式,但是就像所有技术挑战一样,我确信有几种方法可以解决。我想保持文档结构不变。如果需要,我可以在我的应用程序代码中消除额外的结果,但更喜欢数据库中的数据恰到好处。
这就是我要做的......
该集合
Location.id
是应用程序代码中的int集,仅用于创建位置和奖励之间的关系(奖励可能仅在几个位置有效)。以下文档已经减少,重点关注这里的重要内容。
{
"_id" : ObjectId("53728b24e4749ce8ac3f31e7"),
"name" : "Business name",
"locations" : [
{
"name" : "Downtown Norfolk",
"id" : 3
},
{
"name" : "McDonald's Suffolk",
"id" : 4
}
],
"rewards" : [
{
"name" : "Reward for Downtown Norfolk Only",
"locationIDs" : [3]
}
]
}
查询
我需要制作的是每个奖励及其适用位置的清单。我可以使用以下内容获取位置/奖励的完整列表...
collection.aggregate([
{ $unwind: '$rewards' },
{ $unwind: '$locations' },
{ $project: { name: 1, rewards: 1, locations: 1 } }
}
])
查询结果
以下基本上将所有地点加入所有奖励。但是这个奖励只适用于location.id = 3,而不是3和4,所以我需要从结果中消除location.id = 4。我需要继续使用聚合,因为实际查询(此处未显示)包括$ geoNear。
{
"result" : [
{
"_id" : ObjectId("53728b24e4749ce8ac3f31e7"),
"name" : "Business name",
"locations" : {
"name" : "Downtown Norfolk",
"id" : 3
},
"rewards" : {
"name" : "Newport News Only Reward",
"locationIDs" : [3]
}
},
{
"_id" : ObjectId("53728b24e4749ce8ac3f31e7"),
"name" : "Business name",
"locations" : {
"name" : "McDonald's Suffolk",
"id" : 4
},
"rewards" : {
"locationIDs" : [3]
}
}
],
"ok" : 1
}
我想要的查询结果
我要做的是从上面的查询结果中删除最后一个文档,其中locationID不匹配(其中locations.id = 4不在rewards.locationIDs = [3]中)。以下是我想从Mongo回来的内容。
{
"result" : [
{
"_id" : ObjectId("53728b24e4749ce8ac3f31e7"),
"name" : "Business name",
"locations" : {
"name" : "Downtown Norfolk",
"id" : 3
},
"rewards" : {
"name" : "Newport News Only Reward",
"locationIDs" : [
3
]
}
}
],
"ok" : 1
}
非常感谢。
答案 0 :(得分:1)
不确定$ redact会有所帮助。我建议使用$ cmp运算符来比较值,如下所示:
db.ttt.aggregate({$unwind:"$locations"},
{$unwind:"$rewards"},
{$unwind:"$rewards.locationIDs"},
{$project:
{_id:1,
name:1,
locations:1,
rewards:1,
equality:{
$cmp:['$locations.id','$rewards.locationIDs']
}
}
},
{$match:{equality:0}})
它将排除不匹配的文档,然后您需要分组