2012-05-01 16 views
1

私はmongoDBのこのmap/reduceシステムを理解しようとしています。私は私のコレクションに次の基本的なスキーマ/レイアウトを持っています。mongoDB Map/Reduce

{ 
    _id: 1, 
    name: n1, 
    website: w1, 
    tags: [ 
     myTag1, 
     myTag3 
    ] 
} 

{ 
    _id: 2, 
    name: n2, 
    website: w2, 
    tags: [ 
     myTag2, 
     myTag3 
    ] 
} 

{ 
    _id: 3, 
    name: n3, 
    website: w3, 
    tags: [ 
     myTag2, 
     myTag4 
    ] 
} 

ユニークなタグの配列を取得するにはどうすればよいですか?私は、これを私のところに戻して後で使うことを願っています。ところで

{ 
    tags: [ 
     myTag1, 
     myTag2, 
     myTag3, 
     myTag4 
    ] 
} 

これは私が出ているものですが、それはだけではなく、1つのオブジェクトにタグを組み合わせることで、各項目の_idとタグを返します。

var map = function() {emit(this._id,{tags: this.tags});}; 

var reduce = function(key, values) { 
    var t = []; 

    values.forEach(function(doc) { 
     var tags = doc.tags; 
     tags.forEach(function(tag) { 
      if (!(tag in t)) { 
       t.push(tag); 
      } 
     }); 
    }); 

    return {tags: t}; 
}; 

var op = db.businesses.mapReduce(map, reduce, {out: "mr_results"}); 

db[op.result].find(); 

答えて

2

あなたのケースでは、map-reduceを使用する必要はありません。ただ、distinct機能を使用します。

db.businesses.distinct('tags') 

あなたはモンゴシェルでそれを試すことができます。また、あなたが心に留めておく必要があります

> use test 
switched to db test 
> db.businesses.insert({tags: ['tag1', 'tag2']}) 
> db.businesses.insert({tags: ['tag3', 'tag4']}) 
> db.businesses.find() 
{ "_id" : ObjectId("4fa05b2b036495bf4ac9c0cc"), "tags" : [ "tag1", "tag2" ] } 
{ "_id" : ObjectId("4fa05b33036495bf4ac9c0cd"), "tags" : [ "tag3", "tag4" ] } 

> db.businesses.distinct('tags') 
[ "tag1", "tag2", "tag3", "tag4" ] 

/MongoDBのに減らすマップされると、リアルタイムでの照会には適していません。次のようにあなたがそれを行うことができMongoDB MapReduceを使用して

+0

になり、 '[ \t [ myTag1、 myTag3 ]、 \t [ myTag2、 myTag3 ]、 \t [ myTag2、 myTag4 ] ] ' 私は '[ \t [ myTag1、 myTag2、 \t \t myTag3、 \t \t myTag4 ] ]奇妙な' – Brandon

+0

うーんを、必要とします。 mongoシェルの例を使ってアップデートを投稿しました。これはおそらく役に立ちます。 – Matt

+0

それは非常に奇妙です、私の例では何も表示されません – Brandon

1

function m() { 
    this.tags.forEach(function(x) { emit('tag', x); }); 
} 
function r(k, v) { 
    var res = {}; 
    v.forEach(function(x) { res[x] = true; }); 
    return res; 
} 
db.businesses.mapReduce(m, r, {out:'out'}); 
// Now the 'out' collection has a record whose "value" property 
// has a key for each of the tags in the source collection. 
function getTags(coll) { 
    var tags=[], o=db[coll].find()[0].value; 
    for (var i in o) { tags.push(i) } 
    return tags; // Same as Object.keys(db[coll].find()[0].value) 
} 
listTags('out'); // => ['myTag1', 'myTag2', 'myTag3', 'myTag4'] 
関連する問題