我正在尝试在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
]
}
顺便说一下,这就是我想出的,但它只是返回每个项目的_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();
在您的情况下,没有必要使用 map-reduce。只需使用distinct
功能:
db.businesses.distinct('tags')
你可以在 mongo shell 中尝试一下:
> 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不适合实时查询。
使用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']