如何在MongoDB MapReduce JavaScript查询中引用对象数组中对象的每个属性?

时间:2014-10-27 22:11:12

标签: javascript mongodb mapreduce mongodb-query

如何在MongoDB MapReduce JavaScript查询中引用对象数组中对象的每个属性?

这是我的数据:

{
  "_id": ObjectId("544ae3de7a6025f0470041a7"),
  "name": "Bundle 4",
  "product_groups": [
    {
      "name": "camera group",
      "products": [
        {
          "$ref": "products",
          "$id": ObjectId("531a2fcd26718dbd3200002a"),
          "$db": "thisDB"
        },
        {
          "$ref": "products",
          "$id": ObjectId("538baf7c26718d0a55000043"),
          "$db": "thisDB"
        },
        {
          "$ref": "products",
          "$id": ObjectId("538baf7c26718d0a55000045"),
          "$db": "thisDB"
        }
      ]
    },
    {
      "name": "lens group",
      "products": [
        {
          "$ref": "products",
          "$id": ObjectId("531e3ce926718d0d45000112"),
          "$db": "thisDB"
        },
        {
          "$ref": "products",
          "$id": ObjectId("531e3ce926718d0d45000113"),
          "$db": "thisDB"
        }
      ]
    }
  ]
}

这是我的地图功能:(为简单起见,我拿出了reduce选项,因为如果地图不能正常工作并不重要)

var map = function() { emit(this.product_groups, this.product_groups.products); };
db.instant_rebates.mapReduce(
    map,
    {
        out: "map_reduce_example",
        query: {"_id": ObjectId("544ae3de7a6025f0470041a7")}
    }
);

然而问题在于"值"结果中的字段始终显示为" undefined"。为什么?为什么this.product_groups.products不返回产品数组?我该如何解决?

另外,我希望它能为两个product_group中的每一个发出一次TWICE。但到目前为止它只发出ONCE。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

在mapReduce操作下,文档显示为JavaScript对象,因此您需要将它们视为对象并遍历它们。这意味着处理数组的每个成员:

var map = function() { 
    this.product_groups.forEach(function(group) {
        emit( group.name, { products: group.products } );
    });
};
var reduce = function(){};

db.instant_rebates.mapReduce(
    map,
    reduce,
    {
        out: "map_reduce_example",
        query: {"_id": ObjectId("544ae3de7a6025f0470041a7")}
    }
);

“emit”函数的要求既是“key”又是“value”,表示为发出的参数。 “值”必须是单数的,因此要发出一个数据“数组”,您需要将其包装在对象的属性下。 “key”必须是一个单数值,因为它意图将它用作reduce操作中的“分组键”,并且“name”字段应该足够至少为例。

当然,由于文档中有一个顶级数组,您处理“每个元素”,就像使用该函数一样,然后每个结果都“发出”,因此从这个文档中发出“两个”结果。

你还需要至少定义一个“reduce”函数,即使它永远不会被调用,因为所有发出的键都不同,就像这里的情况一样。

所以,它是JavaScript。将列表结构视为列表。

请注意。这就是你的所有问题。如果您想在mapReduce上提出更多问题,请询问其他问题。不要再问这个了。我不想谈论你的字段命名,或详细了解这似乎是如何努力“如何从其他集合中提取数据”,这是你不能做的事情。