1

ドキュメントに辞書フィールドがあります。

「countries」フィールドを含むサンプル ドキュメント:

...
"countries": {
    "us": {
        "uid": "725129b4-debe-47dc-9ab0-aa8aa620e35b"
    },
    "canada": {
        "uid": "83250bc5-49ae-4775-a933-d7a3e9d00d1c"
    },
    "uk": {
        "path": "/uk/",
        "uid": "e32347a9-522c-4c66-be3b-3edfd50c76bb"
    },
    "spain": {
        "path": "/spain/",
        "uid": "93ecd56b-1ed2-4647-bee8-8685183eca2e"
    },
    "india": {
        "path": "/india/",
        "uid": "c4458535-c63b-45e1-bb24-cabbc65d59a4"
    }
}
...

すべてのドキュメントから、「パス」属性が存在する国を取得する必要がありますか?

4

1 に答える 1

0

データ構造を変更することが最善の選択ですが (クエリははるかに効率的で、2 次コレクションを必要としないため、ドキュメントを保存するときにそれを二重に保存する方がよい場合もあります)、MapReduce を試して取得することもできます。データ構造を変更できない場合の結果。増分更新を行う必要がある場合があり、結果が常に最新であるとは限らないことに注意してください。

簡単なバージョン (JavaScript) は次のとおりです。

map = function () {
    // loop through the countries node
    if (this.countries) {
        for(var name in this.countries) {
            if (typeof this.countries[name].path !== 'undefined') {
            // emit a unique combo id so that the reduce will only have
            // one value to reduce later
            emit({id: this._id, country: name}, this.countries[name].path);
            }
        }
    }
};

reduce = function(key, values) {
    // return the one value
    return values;
};

次に、reduce を実行します。

db.so.mapReduce(map, reduce, {out: "so_map"})

次のようなものを生成します(サンプルデータが与えられた場合):

> db.so_map.find()
{ "_id" : { "id" : ObjectId("5183e08be71ddfd99756386c"), "country" : "india" }, "value" : "/india/" }
{ "_id" : { "id" : ObjectId("5183e08be71ddfd99756386c"), "country" : "spain" }, "value" : "/spain/" }
{ "_id" : { "id" : ObjectId("5183e08be71ddfd99756386c"), "country" : "uk" }, "value" : "/uk/" }
于 2013-05-03T16:22:18.873 に答える