我有以下文件
{
"_id": ObjectId("5461363bdfef7c4800146f4b"),
"title": "Plant Overview",
"segments": [
{
"tagBindings": [
{
"id" : ObjectId("54ac12f4b4f22ec30153ea83"),
"tagType" : "Facility"
},
{
"id" : ObjectId("54999a0e899ab5530031535e"),
"tagType" : "Facility"
},
{
"id" : ObjectId("5498189c496623160068831c"),
"tagType" : "Facility"
}
],
"name": "Liberty Lofts - Solar Power Plant",
"id": ObjectId("54637850dfcbe62000a7eddf")
}
]
}
我想查找segments.tagBindings.id等于某些值并且没有任何其他ID的记录。
我使用该查询:
db.ds_dashboards.find({"segments.tagBindings.id": {$in: [ObjectId("54ac12f4b4f22ec30153ea83"), ObjectId("54999a0e899ab5530031535e")]}})
它返回上面的文档。
但我不需要它,因为第三段.tagBindings.id是5498189c496623160068831c
id。
我应该如何更新查询?
答案 0 :(得分:2)
您希望使用聚合并利用$setIsSubset
运算符。所以你的查询看起来像这样:
> db.ds_dashboards.aggregate([
{ "$unwind": "$segments"},
{ "$unwind": "$segments.tagBindings" },
{ "$group": {
"_id": "$_id",
"tagBindings" : { "$addToSet": "$segments.tagBindings.id" }
}
},
{ "$project": {
"isValid": {
"$setIsSubset": [
"$tagBindings",
[ObjectId("54ac12f4b4f22ec30153ea83"),
ObjectId("54999a0e899ab5530031535e")]
]}
}
}
]);
{ "_id" : ObjectId("5461363bdfef7c4800146f4b"), "isValid" : false }
如上所示,给定您的示例文档,上面的查询将返回false。这是因为,正如您所说,ObjectId("5498189c496623160068831c")
中不存在$tagBindings
。如果您修改该数组以包含所述ObjectId
,那么它将返回true。
然后,您可以添加match
子句来过滤掉isValid
为假的结果。最后一个子句看起来像这样:{ "$match": { "isValid": true } }
。
答案 1 :(得分:1)
首先你应该使用$ all来做这个;
db.ds_dashboards.find({"segments.tagBindings.id":
{$all:[ObjectId("54ac12f4b4f22ec30153ea83"), ObjectId("54999a0e899ab5530031535e")]}})
你也可以将它与$ size运算符结合使用以获得完全匹配;
db.ds_dashboards.find({"segments.tagBindings.id":
{$all:[ObjectId("54ac12f4b4f22ec30153ea83"), ObjectId("54999a0e899ab5530031535e")]},
"segments.tagBindings": { $size: 2 }})