我想根据一个特定字段查找最大连续记录数。
我的 db.people
集合在找到基于字段的排序后是:
> db.people.find().sort({ updated_at: 1})
{ "_id" : 1, "name" : "aaa", "flag" : true, "updated_at" : ISODate("2014-02-07T08:42:48.688Z") }
{ "_id" : 2, "name" : "bbb", "flag" : false, "updated_at" : ISODate("2014-02-07T08:43:10Z") }
{ "_id" : 3, "name" : "ccc", "flag" : true, "updated_at" : ISODate("2014-02-07T08:43:40.660Z") }
{ "_id" : 4, "name" : "ddd", "flag" : true, "updated_at" : ISODate("2014-02-07T08:43:51.567Z") }
{ "_id" : 6, "name" : "fff", "flag" : false, "updated_at" : ISODate("2014-02-07T08:44:23.713Z") }
{ "_id" : 7, "name" : "ggg", "flag" : true, "updated_at" : ISODate("2014-02-07T08:44:44.639Z") }
{ "_id" : 8, "name" : "hhh", "flag" : true, "updated_at" : ISODate("2014-02-07T08:44:51.415Z") }
{ "_id" : 5, "name" : "eee", "flag" : true, "updated_at" : ISODate("2014-02-07T08:55:24.917Z") }
在上述记录中,flag
属性值连续出现true
的地方有两处。即
record with _id 3 - record with _id 4 (2 consecutive records)
和
record with _id 7 - record with _id 8 - record with _id 5 (3 consecutive records)
但是,我想要 mongo 查询搜索的最大连续数。即 3
.
有可能得到这样的结果吗?
我用谷歌搜索了一下,发现了一个使用 Map-Reduce
的类似解决方案这里 https://stackoverflow.com/a/7408639/1120530 .
我是 mongodb 新手,无法理解 map-reduce
文档,特别是如何在上述场景中应用它。
最佳答案
你可以做这个mapReduce操作。
首先是映射器:
var mapper = function () {
if ( this.flag == true ) {
totalCount++;
} else {
totalCount = 0;
}
if ( totalCount != 0 ) {
emit (
counter,
{ _id: this._id, totalCount: totalCount }
);
} else {
counter++;
}
};
它会记录在标志中看到 true
值的总次数。如果该计数大于 1,则我们发出该值,还包含文档 _id
。当标志为 false
时,另一个用于键的计数器会递增,以便为匹配项提供分组“键”。
然后是reducer:
var reducer = function ( key, values ) {
var result = { docs: [] };
values.forEach(function(value) {
result.docs.push(value._id);
result.totalCount = value.totalCount;
});
return result;
};
只需将 _id
值与 totalCount 一起推送到结果数组中。
然后运行:
db.people.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": {
"totalCount": 0,
"counter": 0
},
"sort": { "updated_at": 1 }
}
)
因此,使用 mapper
和 reducer
函数,我们随后定义“作用域”中使用的全局变量并传入 所需的“排序” updated_at
日期。结果如下:
{
"results" : [
{
"_id" : 1,
"value" : {
"docs" : [
3,
4
],
"totalCount" : 2
}
},
{
"_id" : 2,
"value" : {
"docs" : [
7,
8,
5
],
"totalCount" : 3
}
}
],
"timeMillis" : 2,
"counts" : {
"input" : 7,
"emit" : 5,
"reduce" : 2,
"output" : 2
},
"ok" : 1,
}
当然,您可以跳过 totalCount
变量而只使用数组长度,这将是相同的。但是既然你想使用那个计数器,它就被添加进去了。但这就是原则。
所以是的,这是一个适合 mapReduce 的问题,现在你有一个例子。
关于mongodb - 根据 Mongodb Query 中的一个字段查找最大连续记录数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21621754/