我有一组文件(称之为“日志”),看起来与此类似:
{
"_id" : ObjectId("52f523892491e4d58e85d70a"),
"ds_id" : "534d35d72491de267ca08e96",
"eT" : NumberLong(1391784000),
"vars" : [{
"n" : "ActPow",
"val" : 73.4186401367188,
"u" : "kWh",
"dt" : "REAL",
"cM" : "AVE",
"Q" : 99
}, {
"n" : "WinSpe",
"val" : 3.06327962875366,
"u" : "m/s",
"dt" : "REAL",
"cM" : "AVE",
"Q" : 99
}]
}
vars
数组包含大约150个子文档,而不仅仅是我上面显示的两个子文档。我现在要做的是运行一个查询,该查询检索上面显示的val
数组中两个子文档的vars
。
使用聚合框架,我已经能够提出以下内容:
db.logs.aggregate( [
{ $match :
{ ds_id: "534d35d72491de267ca08e96",
eT: { $lt : 1391784000 },
vars: { $elemMatch: { n: "PowCrvVld", val: 3 }}
}
},
{ $unwind : "$vars" },
{ $match :
{ "vars.n" : { $in : ["WinSpe", "ActPow"] }},
{ $project : { "vars.n" : 1, N : 1}
}
]);
虽然这有效,但在运行较大的查询时,我遇到了16MB的限制。看到我在vars
数组中有大约150个子文档,如果可能,我还想避免使用$unwind
。
使用常规查询并使用$elemMatch
我已经能够检索其中一个值:
db.logs.TenMinLog.find({
ds_id : "534d35d72491de267ca08e96",
eT : { $lt : 1391784000 },
vars : { $elemMatch : { n : "PowCrvVld", val : 3 }
}
}, {
ds_id : 1,
vars : { $elemMatch : { n : "ActPow", cM : "AVE" }
});
我的问题是,如果有一种方法可以在查找的<projection>
部分多次对数组使用$ elemMatch。如果没有,是否有另一种方法可以轻松检索这两个子文档而不使用$ unwind?我也愿意接受我可能不了解的更高效的其他建议。谢谢!
答案 0 :(得分:1)
如果您使用的是MongoDB 2.6,则可以使用$redact运算符修剪vars数组中的元素。
在MongoDB 2.6中,您还可以将结果作为游标返回,以避免16MB的限制。来自文档:
在MongoDB 2.6中,aggregate命令可以将结果作为游标或结果返回 将结果存储在一个不受大小限制的集合中 限制。 db.collection.aggregate()返回一个游标并可以返回 任何大小的结果集。
答案 1 :(得分:1)
我强烈考虑迁移到MongoDB 2.6版本。聚合已得到增强,可返回一个消除16MB文档限制的游标:
在版本2.6中更改:
db.collection.aggregate()方法返回一个游标并可以返回 任何大小的结果集。以前的版本在a中返回所有结果 单个文档,结果集的大小限制为16 兆字节。
http://docs.mongodb.org/manual/core/aggregation-pipeline/
此外,您可能会发现许多增强功能可用于更复杂的聚合查询:
聚合增强功能
聚合管道添加了返回任何结果集的功能 大小,通过返回游标或将输出写入a 采集。此外,聚合管道支持变量 并添加新操作来处理集合和编辑数据。
db.collection.aggregate()现在返回一个游标,它启用了 聚合管道返回任何大小的结果集。聚合 管道现在支持解释操作以帮助分析 聚合操作。聚合现在可以使用更高效 基于外部磁盘的排序过程。
新的管道阶段:
- $ out stage to output to a collection。
- $ redact阶段允许其他控件访问数据。
新的或修改过的运营商:
- 设置表达式运算符。
- $ let和$ map运算符允许使用变量。
- $ literal operator和$ size operator。
- $ cond表达式现在接受对象或数组。
答案 2 :(得分:0)
也许这有效。
db.logs.TenMinLog.find({
ds_id : "534d35d72491de267ca08e96",
eT : { $lt : 1391784000 },
vars : { $or: [{ $elemMatch : { n : "PowCrvVld", val : 3 },
{ $elemMatch : { n : <whatever>, val : <whatever> }]
}
}
}, {
ds_id : 1,
vars : { $elemMatch : { n : "ActPow", cM : "AVE" }
});
希望它能按你的意愿运作。