如何在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")}
}
);
然而,问题是结果中的"值"字段总是显示为"未定义"。为什么?为什么this.product_groups.products不返回products数组?我该如何解决这个问题?
此外,我希望它发射两次,两个product_group中的每一个都发射一次。但到目前为止,它只发射一次。我该怎么解决?
在mapReduce操作下,文档以JavaScript对象的形式呈现,因此您需要将它们视为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"必须是一个奇异值,因为它打算在reduce操作中用作"分组键",并且"name"字段至少应该足够。
自然地,由于文档中有一个顶级数组,您可以像处理函数一样处理"每个元素",然后每个结果都是"发出的",因此从这一个文档中发出"两个"结果。
您还需要至少定义一个"reduce"函数,即使它从未被调用,因为所有发出的键都不同,就像这里的情况一样。
所以,它是JavaScript。将列表结构视为列表。
请注意。这就是你的全部问题。如果您想在mapReduce上提出更多问题,请提出其他问题。不要再问这个了。我不想谈论你的字段命名,也不想详细说明这似乎是如何实现"我如何从其他集合中提取数据"的,这是你无法做到的。