2

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 に制限したいと思います。

4

2 に答える 2