假设以下集合定义,其中示例是此类集合中的一个条目:
enumeration : {
name: 'enumeration-1'
elements: [
{
value: 'value-1'
tags: ['tag-1', 'tag-2']
},
{
value: 'value-2',
tags: ['tag-2', 'tag'-3']
},
{
value: 'value-3'
tags: ['tag-3', 'tag-4']
}
]
}返回特定枚举非常简单:
db.enumerations.find({ name: 'enumeration-1' })但是,我需要对查询进行扩充,使其只返回每个元素在标记列表中至少有一个标记元素。考虑以下参数:
1. name: 'enumeration-1'
2. tags: ['tag-1', 'tag-4']我需要输出为:
['value-1', 'value-3']也就是说,我只需要包含一个或多个指定标记的元素的值,这些标记包含在枚举1中。如果可能的话,查询看起来会是什么样子?返回完整的元素也很好。我使用的是Mongo 2.6.9。
发布于 2016-09-16 23:29:31
您可以使用聚合框架。find查询中的另一种选择是$elemMatch或$projection,这两种查询都只支持返回数组中的第一个匹配元素,因此它们不适用于您的情况,因为您想要所有的值,而且它们无论如何都不适用于您的情况(我认为)。您需要按数组值进行过滤,但要投射其他值。
但这里是它如何在聚合框架中工作的(如果你需要,你可以在最后做所有的事情,例如使结果唯一等)。
db.enumerations.aggregate(
{$match:{"enumeration.name":"enum-1"}},
{$unwind:"$enumeration.elements"},
{$unwind:"$enumeration.elements.tags"},
{$match:{"enumeration.elements.tags":{$in:["tag-1","tag-4"]}}},
{$project:{"enumeration.elements.value":1}})发布于 2016-09-16 22:47:26
不确定这是否有效(从内存中),但似乎您需要查看用于数组查询的$elemMatch,然后查看要查找的第二个可选参数,该参数用于投影。
db.enumerations.find({ name: 'enumeration-1', elements : {$elemMatch : { $in : ['tag-1', 'tag-4']}}}, {_id:0, 'elements.value':1})发布于 2016-09-16 23:06:24
您可以运行以下聚合操作,使用set operators作为黑客(脏操作)来生成修剪后的元素数组:
var query = {
"name": "enumeration-1",
"tags": ["tag-1", "tag-4"]
};
db.enumerations.aggregate([
{ "$match": { "name": query.name } },
{
"$project": {
"name": 1,
"elements": {
"$setDifference": [
{
"$map": {
"input": "$elements",
"as": "el",
"in": {
"$cond": [
{
"$setEquals": [
{
"$setIntersection": [
"$$el.tags", query.tags
]
},
[]
]
},
false,
"$$el"
]
}
}
},
[false]
]
}
}
}
])https://stackoverflow.com/questions/39533311
复制相似问题