0

私は以下の地図を持っています:

var mapFunction = function() {

if(this.url.match(/http:\/\/test.com\/category\/.*?\/checkout/)) {
var key=this.em;
var value = {
    url : 'checkout',
    count : 1,
    account_id:this.accId

}emit(key,value); };
if(this.url.match(/http:\/\/test.com\/landing/)) {
var key=this.em;
var value = {
    url : 'landing',
    count : 1,
    account_id:this.accId

}emit(key,value); };

}

次に、reduce を以下のように定義しました。

var reduceFunction = function (keys, values) {
var reducedValue = {count_checkout:0, count_landing:0};
for (var idx = 0; idx < values.length; idx++) {
    if(values[idx].url=='checkout'){
        reducedValue.count_checkout++;
    }
    else {
        reducedValue.count_landing++;
    }
}
return reducedValue;
} 

ここで、レコードが 1 つしかないとします。

{
        "_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "testing@test.com",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}

マップを起動すると、以下のように縮小されます。

db.test_views.mapReduce(mapFunction,reduceFunction,{out:{inline:1}})

以下の結果が返されます。

{
          "_id" : "testing@test.com",
          "value" : {
                  "url" : "checkout",
                  "count" : 1,
                  "account_id" : 123
          }
  }

つまり、基本的にマップを返します。ここで、この電子メール ID に別のドキュメントを追加するとします。最終的には以下のようになります。

{
        "_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "testing@test.com",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}
{
        "_id" : ObjectId("516a7e1b6dad5949ddf3f7b7"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "testing@test.com",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:59:55.326Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}

次に、もう一度マップの縮小を実行すると、適切な結果が得られます

{
         "_id" : "testing@test.com",
         "value" : {
                 "count_checkout" : 2,
                 "count_landing" : 0
         }
 }

単一のドキュメントのマップが返され、reduce でカウントされない理由を理解するために、誰か助けてください。

手伝ってくれてありがとう。

-ラリット

4

2 に答える 2

1

単一のドキュメントのマップが返され、reduce でカウントされない理由を理解するために、誰か助けてください。

Reduce ステップは、同じキーを持つドキュメントを 1 つの結果ドキュメントに結合します。Map 関数によって発行されたデータにキーが 1 つしかない場合、データは既に「縮小」されており、reduce() は呼び出されません。

これは、MapReduceアルゴリズムの予想される動作です。

于 2013-04-14T22:16:50.180 に答える
0

reduce 関数は、map 関数が発行するのと同じ型の値オブジェクトを返す必要があります。
経験したように、キーに単一の値が関連付けられている場合、reduce 関数はまったく呼び出されません。

MongoDB MapReduce ドキュメントから:

reduce 関数の要件:
...
返されるオブジェクトの型は、次の操作が true であることを確認するために、マップ関数によって発行された値の型と同じでなければなりません:
reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( キー, [ C, A, B ] )

于 2013-04-14T23:29:01.113 に答える