如何在MongoDB MapReduce中的map函数中访问this._id?

时间:2011-10-24 13:09:20

标签: mongodb

我在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。我不知道为什么。

问题:

  1. 如何获取 map 函数中当前对象的_id以用于MapReduce? this._id或此['_ id']不起作用。
  2. 为什么 m1 m2 完全不相同?

1 个答案:

答案 0 :(得分:3)

让它工作......我犯了很简单的JS错误:

  1. map函数中的内部forEach()似乎覆盖了'this'对象;这不再是主文档(具有_id),而是循环内的迭代对象... ...
  2. ...或者只是因为在JS中for..in循环只返回键,而不是值,即

    for(v in values){

  3. 现在需要

    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...
    ...
    }
    

    可能会很好。

    希望这有助于某人。