首页 文章

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

提问于
浏览
0

我正在Mongo中进行MapReduce,为某些文档生成令牌的反向索引 . 我在map函数中访问文档的_id时遇到问题 .

示例文档:

{
        "_id" : ObjectId("4ea42a2c6fe22bf01f000d2d"),
        "attributes" : {
                "name" : "JCDR 50W38C",
                "upi-tokens" : [
                        "50w38c",
                        "jcdr"
                ]
        },
        "sku" : "143669259486830515"
}

(字段ttributes ['upi-tokens']是我想为其创建反向索引的文本标记列表 . )

Map 功能(问题的根源):

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" } )

PROBLEM 结果集合到处都有 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 . 我不知道为什么 .

问题:

  • 如何获取 map 函数中当前对象的_id以用于MapReduce? this._id或者这个['_id']不起作用 .

  • 为什么 m1m2 完全不相同?

1 回答

  • 3

    搞定了......我犯了很简单的JS错误:

    Map 函数中的

    • inner forEach()似乎覆盖了'this'对象;这不再是主文档(具有_id),而是循环内的迭代对象)...

    • ...或者只是因为在JS中for..in循环只返回键,而不是值,即

    for(v in values){

    现在需要

    values[v]
    

    访问实际的数组值 . 咄...

    The way I circumvented mistake #1 是通过在map函数中使用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...
    ...
    }
    

    可能会工作得很好 .

    希望这有助于某人 .

相关问题