如何在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。我该如何解决这个问题?
答案 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上提出更多问题,请询问其他问题。不要再问这个了。我不想谈论你的字段命名,或详细了解这似乎是如何努力“如何从其他集合中提取数据”,这是你不能做的事情。