我正在尝试通过匹配数组中的文档来查询集合,让我们调用Telemetry
:
var hardwareIDs = ['A','B','C'];
Telemetry.find({ hardwareID: { $in: hardwareIDs }});
以下是Telemetry
记录的示例:
{
_id: xxxx,
insertedAtUTC: xxxx,
hardwareID: xxxx,
year: 2016,
month: 2,
day: 31,
hour: 0,
data: []
}
但我发现很难做到的是,让我们说,每个匹配查询的最新3个文档。因此,我有效地返回一个看起来类似于此的游标:
[
{ insertedAtUTC: 3, hardwareID: "A", ... },
{ insertedAtUTC: 2, hardwareID: "A", ... },
{ insertedAtUTC: 1, hardwareID: "A", ... },
{ insertedAtUTC: 3, hardwareID: "B", ... },
{ insertedAtUTC: 2, hardwareID: "B", ... },
{ insertedAtUTC: 1, hardwareID: "B", ... },
{ insertedAtUTC: 3, hardwareID: "C", ... },
{ insertedAtUTC: 2, hardwareID: "C", ... },
{ insertedAtUTC: 1, hardwareID: "C", ... }
]
有关如何制定MongoDB查询以解决此问题的任何想法?
我用meteor
标记了这一点,因为我在MeteorJS中使用MongoDB。我目前正在尝试发布一个轻量级游标,因为Telemetry
集合相当大,但我认为这不会对解决方案产生任何影响。
答案 0 :(得分:1)
你可以通过使用mapreduce来实现:发出所有hardwareID而不是reduce,通过insertedAtUTC对它们进行排序。
此外,如果您想要更多地过滤字段的投影,您可以应用聚合,展开并对文档进行投影。 看看我的示例script.js:
use stackoverflow
db.dropDatabase()
db.telemetry.insert(
[
{ hardwareID: "C", insertedAtUTC: 2 },
{ hardwareID: "C", insertedAtUTC: 3 },
{ hardwareID: "C", insertedAtUTC: 1 },
{ hardwareID: "A", insertedAtUTC: 1 },
{ hardwareID: "A", insertedAtUTC: 2 },
{ hardwareID: "A", insertedAtUTC: 3 },
{ hardwareID: "B", insertedAtUTC: 3 },
{ hardwareID: "B", insertedAtUTC: 2 },
{ hardwareID: "B", insertedAtUTC: 1 },
{ hardwareID: "X", insertedAtUTC: 2 },
{ hardwareID: "X", insertedAtUTC: 1 }
]
)
var hardwareIDs = ['A','B','C'];
var map = function map(){
emit(this.hardwareID, this);
};
var reduce = function(key, values){
var sorted_values = values.sort(function(first, second) {
return second.insertedAtUTC - first.insertedAtUTC;
}).slice(0,2);
return {key, sorted_values};
};
db.runCommand({"mapReduce":"telemetry", map:map, reduce:reduce, out:{replace:"telemetry2"}, query:{ hardwareID: { $in: hardwareIDs }}})
var result = db.telemetry2.aggregate(
[
{ $unwind : {path: '$value.sorted_values' }},
{ $project: {
_id: '$value.sorted_values._id',
hardwareID: '$value.sorted_values.hardwareID',
insertedAtUTC: '$value.sorted_values.insertedAtUTC'
}
}
]
);
while(result.hasNext()){
printjson(result.next());
}
您可以通过
在控制台中运行脚本mongo < script.js