Man*_*noj 11 mongodb mongodb-query aggregation-framework
我有一个像mongodb的文件
{
"_id" : ObjectId("54e66b2da7b5f3a92e09dc6c"),
"SomeMetric" : [
{
//some object
}
{
//some object
}
],
"FilterMetric" : [
{
"min" : "0.00",
"max" : "16.83",
"avg" : "0.00",
"class" : "s1"
},
{
"min" : "0.00",
"max" : "16.83",
"avg" : "0.00",
"class" : "s2"
},
{
"min" : "0.00",
"max" : "16.83",
"avg" : "0.00",
"class" : "s1"
},
{
"min" : "0.00",
"max" : "16.83",
"avg" : "0.00",
"class" : "s2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
通常它包含许多这样的嵌套数组.我想单独设计一个指标,只有具有我搜索条件的数组.我有查询
db.sample.find(
{"filtermetric.class" : "s2"},{"filtermetric" : { $elemMatch : {class: "s2"}}}
)
Run Code Online (Sandbox Code Playgroud)
这只给了我数组中的第一个对象.不返回类:s2的第二个对象.
如果我试试
db.sample.find(
{"filtermetric" : { $elemMatch : {class: "s2"}}}
)
Run Code Online (Sandbox Code Playgroud)
它给了我数组中的所有4个对象.
在这种情况下,如何获得符合条件的所有对象?
Nei*_*unn 17
您不能以任何形式的基本.find()查询返回与您的条件匹配的数组的多个元素.要匹配多个元素,您需要使用该.aggregate()方法.
这里的主要区别在于"查询"完全符合它的目的,并匹配符合条件的"文档".您可以尝试在投影参数中使用位置$运算符,但规则是它只匹配与查询条件匹配的"第一个"数组元素.
要为多个数组元素"过滤",请按以下步骤操作:
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Unwind the array to denormalize
{ "$unwind": "$filtermetric" },
// Match specific array elements
{ "$match": { "filtermetric.class": "s2" } },
// Group back to array form
{ "$group": {
"_id": "$_id",
"filtermetric": { "$push": "$filtermetric" }
}}
])
Run Code Online (Sandbox Code Playgroud)
在版本为2.6或更高版本的MongoDB的现代版本中,您可以使用以下命令$redact:
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Redact the entries that do not match
{ "$redact": {
"$cond": [
{ "$eq": [ { "$ifNull": [ "$class", "s2" ] }, "s2" ] },
"$$DESCEND",
"$$PRUNE"
]
}}
])
Run Code Online (Sandbox Code Playgroud)
这可能是你最有效的选择,但它是递归的,所以首先考虑你的文档结构,因为任何级别的任何其他条件都不能存在相同的命名字段.
可能更安全,但只有在数组中的结果是"独一无二"有用的是这种技术用$map和$setDifference:
db.sample.aggregate([
{ "$project": {
"filtermetric": { "$setDifference": [
{ "$map": [
"input": "$filtermetric",
"as": "el",
"in": {"$cond": [
{ "$eq": [ "$$el.class", "s2" ] },
"$$el",
false
]}
]},
[false]
]}
}}
])
Run Code Online (Sandbox Code Playgroud)
还要注意,在操作管道阶段$group和$project操作管道阶段中,您需要指定要在该阶段的结果文档中返回的所有字段.
最后要注意的是,$elemMatch当您只查询数组中单个键的值时,不需要这样做.当仅访问阵列的单个键时,首选"点符号"并建议使用.$elemMatch应该只在数组"element"中的文档中的"多个"键需要匹配查询条件时才需要.
| 归档时间: |
|
| 查看次数: |
10697 次 |
| 最近记录: |