MapReduce 関数に問題があります。目標は、特定の緯度/経度内の上位の会場のリストを取得することvid
ですuser_id
。
サンプル データ セットを次に示します。
{ "_id" : ObjectId("51f9234feb97ff0700000046"), "checkin_id" : 39286249, "created_at" : ISODate("2013-07-31T14:47:11Z"), "loc" : { "lat" : 42.3672, "lon" : -86.2681 }, "icv" : 1, "ipv" : 1, "vid" : 348442, "user_id" : 151556, "bid" : 9346, "pid" : 549 }
{ "_id" : ObjectId("51f9234b488fff0700000006"), "checkin_id" : 39286247, "created_at" : ISODate("2013-07-31T14:47:07Z"), "loc" : { "lat" : 55.6721, "lon" : 12.5576 }, "icv" : 1, "ipv" : 1, "vid" : 3124, "user_id" : 472486, "bid" : 7983, "pid" : 2813 }
...
これが私のマップ関数です:
map1 = function() {
var tempDoc = {};
tempDoc[this.user_id] = 1;
emit(this.vid, {
users: tempDoc,
count: 1
});
}
そして減らす:
reduce1 = function(key, values) {
var summary = {
users: {},
total: 0
};
values.forEach(function (doc) {
// increment total for every value
summary.total += doc.count;
// Object.extend() will only add keys from the right object that do not exist on the left object
Object.extend(summary.users, doc.user);
});
return summary;
};
私の geo_query:
var d = Date("2013-07-31T14:47:11Z");
var geo_query = {loc: {$near: [40.758318,-73.952985], $maxDistance: 25}, "icv":1, "created_at": {$gte: d}};
そして最後に mapReduce クエリ:
var res = db.myColelction.mapReduce(map1, reduce1, { out : { inline : 1 }, query : geo_query });
返される結果は reduce 関数に一致しますが、finalize1 関数にはヒットしません。
...
{
"_id" : 609096,
"value" : {
"users" : {
"487586" : 1
},
"count" : 1
}
},
{
"_id" : 622448,
"value" : {
"users" : {
"313755" : 1,
"443180" : 1
},
"total" : 4
}
},
...
この時点で、良い結果セットが得られたと思いますが、$near
関数は近くにある 100 の会場のみをスキャンし、すべての会場 (この半径 (25m) に一致するすべてのドキュメント) をスキャンして、すべての会場を調べたいと考えています。それらをグループ化し、その期間の一意のユーザーを数えます. 検索し、ドキュメントを見ましたが、解決策がわかりません. 参加者はいますか?
私にとっての最終的な結果は、「合計」属性によって結果を並べ替えて制限することです。理想的には、総降順でソートし、15 に制限したいと思います。