查询所有元素的字段值相同的子文档数组



我需要在Mongo数据库集合中查找元素,该集合以对象数组为元素,以便该数组中所有元素的一个字段具有相同的值。

条目的格式如下:

{"tag":
{"tag": "val"},
"tags":
[{"foo": "val", "bar": int}, {"foo": "val", "bar": int}, {"foo": "val", "bar": int}]}
}

我是MongoDB的新手,但查了一些东西,我读过$and$all$in,但似乎没有一个能做我想做的事。

这里有一个例子,有四个文档:

{"tag1":
{"tag11": "val11"},
"tags":
[{"foo": "val", "bar": 1}, {"foo": "val", "bar": 2}, {"foo": "val3", "bar": 1}]}
}
{"tag1":
{"tag11": "val21"},
{"tags":
[{"foo": "val4", "bar": 2}, {"foo": "val6", "bar": 2}, {"foo": "val3", "bar": 2}]}
}
{"tag1":
{"tag11": "val21"},
{"tags":
[{"foo": "val4", "bar": 4}, {"foo": "val6", "bar": 2}, {"foo": "val3", "bar": 3}]}
}
{"tag1":
{"tag11": "val21"},
{"tags":
[{"foo": "val5", "bar": 2}, {"foo": "val5", "bar": 2}, {"foo": "val5", "bar": 2}]}
}

例如,我需要一个查询来查找所有具有tags数组元素且bar值为2的条目。在上面的例子中,它将返回第二个也是最后一个。

结果是:

(2)
{"tag1":
{"tag11": "val21"},
{"tags":
[{"foo": "val4", "bar": 2}, {"foo": "val6", "bar": 2}, {"foo": "val3", "bar": 2}]}
}
(4)
{"tag1":
{"tag11": "val21"},
{"tags":
[{"foo": "val5", "bar": 2}, {"foo": "val5", "bar": 2}, {"foo": "val5", "bar": 2}]}
}

(#(用于指出索引。

您可以使用聚合查询在tags数组上迭代,并发现所有tags.bar值都相同(对于每个文档(。

示例foobar集合:

{ "_id" : 1, "tags" : [ { "foo" : "val4", "bar" : 2 }, { "foo" : "val6", "bar" : 2 }, { "foo" : "val3", "bar" : 2 } ] }
{ "_id" : 2, "tags" : [ { "foo" : "val2", "bar" : 3 }, { "foo" : "val3", "bar" : 2 }, { "foo" : "val4", "bar" : 2 } ] }
{ "_id" : 3, "tags" : [ { "foo" : "val2", "bar" : 2 }, { "foo" : "val3", "bar" : 2 }, { "foo" : "val4", "bar" : 9 } ] }
{ "_id" : 4, "tags" : [ { "foo" : "val2", "bar" : 4 }, { "foo" : "val3", "bar" : 4 }, { "foo" : "val4", "bar" : 4 } ] }


查询:

db.foobar.aggregate( [ 
{ $addFields: { firstBar: {$arrayElemAt: [ "$tags.bar", 0 ] } } }, 
{ $addFields: { tagBarMatch: { $map: { 
input: "$tags", 
as: "tagEle", 
in: { 
$cond: { if: { $eq: [ "$$tagEle.bar","$firstBar"  ] }, 
then: true, 
else: false 
} 
}
} } } }, 
{ $addFields: { tagBarMatch: { $allElementsTrue: [ "$tagBarMatch" ] } } },
{ $match: { tagBarMatch: true } },
{ $project: { _id: 1, tags: 1 } }
] )


输出:

{ "_id" : 1, "tags" : [ { "foo" : "val4", "bar" : 2 }, { "foo" : "val6", "bar" : 2 }, { "foo" : "val3", "bar" : 2 } ] }
{ "_id" : 4, "tags" : [ { "foo" : "val2", "bar" : 4 }, { "foo" : "val3", "bar" : 4 }, { "foo" : "val4", "bar" : 4 } ] }

您可以像这样使用$elemMatch。。。

db.collections.find({tag1.tags: {$elemMatch: {tag1.tags.bar:2}})

最新更新