我在Mongo中进行MapReduce,为某些文档生成令牌的反向索引。我无法在地图功能中访问文档的_id。
示例文件:
{
"_id" : ObjectId("4ea42a2c6fe22bf01f000d2d"),
"attributes" : {
"name" : "JCDR 50W38C",
"upi-tokens" : [
"50w38c",
"jcdr"
]
},
"sku" : "143669259486830515"
}
(字段ttributes ['upi-tokens']是我想为其创建反向索引的文本标记列表。)
地图功能(问题的根源):
m = function () {
this.attributes['upi-tokens'].forEach(
function (token) { emit(token, {ids: [ this._id ]} ); }
); }
减少功能:
r = function (key, values) {
var results = new Array;
for (v in values) {
results = results.concat(v.ids);
}
return {ids:results};
}
MapReduce电话:
db.offers.mapReduce(m, r, { out: "outcollection" } )
问题结果集合的 null 值到处都是我期望的id而不是实际的ObjectID字符串。
可能的原因:
我期待以下两个函数是等价的,但它们不是。
m1 = function (d) { print(d['_id']); }
m2 = function () { print(this['_id']); }
现在我跑:
db.offers.find().forEach(m1)
db.offers.find().forEach(m2)
区别在于m2为每个文档打印 undefined ,而m1根据需要打印id。我不知道为什么。
问题:
答案 0 :(得分:3)
让它工作......我犯了很简单的JS错误:
...或者只是因为在JS中for..in循环只返回键,而不是值,即
for(v in values){
现在需要
values[v]
访问实际的数组值。咄...
我绕过错误#1 的方法是在地图函数中使用for..in循环而不是... forEach()循环:
m = function () {
for (t in this.attributes['upi-tokens']) {
var token = this.attributes['upi-tokens'][t];
emit (token, { ids: [ this._id ] });
}
}
这样“这个”指的是它需要的东西。
也可以这样做:
that = this;
this.attributes['upi-tokens'].forEach( function (d) {
...
that._id...
...
}
可能会很好。
希望这有助于某人。