1

Map Reduce を使用しています。問題は、いいえの場合です。ドキュメントの入力が 100 を超えている場合、期待どおりの結果が得られません。結果のうち、いいえの場合。入力ドキュメントの数が <= 100 の場合、期待どおりの結果が得られます。

私が得ているサンプル出力:

{
    "_id" : "5504",
    "value" : [
            ObjectId("51c921bae4b0f0f776b339d2"),
            ObjectId("51b06b5be4b021e44bc69755")
    ]
}

問題:ユーザー (id:5504) のドキュメントが 100 以下の場合、その数のドキュメントを取得できません。出力配列内の ID の数ですが、no. ドキュメントの数が 100 を超える場合、出力配列に含まれる ID はほとんどありません。いいえのときに上記の出力を得ました。このユーザーのドキュメントの数は 101 でしたが、100 のときに 100 の ID を取得しました。この奇妙な動作の理由と、これに対する解決策は何ですか?

マップ機能:

db.system.js.save({

    _id: "map1",

    value: function () {
        var value = {
            "data": [{
                "_id": this._id,
                "creation_time": this.creation_time
            }]
        };
        emit(this.user_id, value);
    }
});

減少機能:

db.system.js.save({

    _id: "reduce1",

    value: function (key, values) {
        var reducedValue = [];
        for (var i = 0; i < values.length; i++) {
            reducedValue.push({
                "_id": values[i].data[0]._id,
                "creation_time": values[i].data[0].creation_time
            });
        }
        return {
            data: reducedValue
        };
    }
});

ファイナライズ機能:

db.system.js.save({

    _id: "finalize1",

    value: function (key, reducedValue) {
        var a = reducedValue.data.sort(compare1);
        var ids = [];
        for (var i = 0; i < a.length; i++) {
            ids.push(a[i]._id);
        }
        return ids;
    }
});

比較機能:

db.system.js.save({

    _id: "compare1",

    value: function (a, b) {
        if (a.creation_time < b.creation_time) return 1;
        if (a.creation_time > b.creation_time) return -1;
        return 0;
    }
});

MapReduce() 呼び出し

db.notifications.mapReduce(map1, reduce1, {out: "notifications_result", query: {delivered:true, user_id:"5504"}, finalize: finalize1});
4

1 に答える 1

1

MongoDB は reduce 関数を何度も呼び出す可能性があるため、Function Idempotenceを確保する必要があります。reduce 関数を少し変更すると、問題が解決します。

db.system.js.save({

    _id: "reduce1",

    value: function (key, values) {
        var reducedValue = [];
        for (var i = 0; i < values.length; i++) {
            for(var j = 0; j < values[i].data.length; j++) {
                reducedValue.push({
                    "_id": values[i].data[j]._id,
                    "creation_time": values[i].data[j].creation_time
                });   
            }

        }
        return {
            data: reducedValue
        };
    }
});

他の呼び出しの戻り値配列values[i].dataにあるため、配列もトラバースされることに注意してください。reduce1values

于 2013-07-05T12:27:38.927 に答える