1

mongoDB でこのマップ/リデュース システムを理解しようとしています。私のコレクションには、次の基本的なスキーマ/レイアウトがあります。

{
    _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
    ]
}

ちなみにこれは私が思いついたものですが、タグを単一のオブジェクトに結合するのではなく、各アイテムの _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();
4

2 に答える 2

3

あなたの場合、 map-reduce を使用する必要はありません。関数を使用するだけdistinctです:

db.businesses.distinct('tags')

mongo シェルで試すことができます。

> 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 の map/reduce はリアルタイムのクエリには適していないことに注意してください。

于 2012-05-01T21:48:16.893 に答える
1

MongoDB MapReduceを使用すると、次のように実行できます。

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']
于 2012-05-01T22:36:07.743 に答える