正如标题所说,我需要检索MongoDB集合中所有键的名称,但我需要根据每个文档所具有的键/值对进行拆分。这是我笨重的比喻:如果你想象原始的集合是一个动物园,我需要一个新的集合,其中包含Zebras拥有的所有密钥,狮子会拥有的所有密钥以及长颈鹿拥有的所有密钥。不同的动物类型共享许多相同的键,但这些键是针对每种类型的动物特定的(因为用户需要能够(例如)搜索高于3英尺的斑马和长度小于10英尺的长颈鹿)。
这里有一些我运行良好的示例代码 - 它抓住了我整个集合中的所有唯一键并将它们放入自己的集合中:
db.runCommand({
"mapreduce" : "MyZoo",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "MyZoo" + "_keys"
})
我喜欢这个命令的一个版本,它会查看MyZoo
动物的"type":"zebra"
集合,找到所有唯一的键,并将它们放在一个新的集合中{{{ 1}}) - 然后为MyZoo_keys
&做同样的事情"type":"lion"
,为每个"type":"giraffe"
提供自己的密钥数组。
这是我开始的收藏品:
"type"
这就是我希望{
"name": "Zebra1",
"height": "300",
"weight": "900",
"type": "zebra"
"zebraSpecific1": "somevalue"
},
{
"name": "Lion1",
"height": "325",
"weight": "1200",
"type": "lion",
},
{
"name": "Zebra2",
"height": "500",
"weight": "2100",
"type": "zebra",
"zebraSpecific2": "somevalue"
},
{
"name": "Giraffe",
"height": "4800",
"weight": "2400",
"type": "giraffe"
"giraffeSpecific1": "somevalue",
"giraffeSpecific2": "someothervalue"
}
系列的样子:
MyZoo_keys
这可能是不完美的JSON,但你明白了......
谢谢!
答案 0 :(得分:2)
您可以修改代码,以便以更易读,更有条理的格式转储结果。
map
功能:
Emit
动物的type
作为键,以及一系列键
每只动物(文件)。省略_id
字段。代码:
var map = function(){
var keys = [];
Object.keys(this).forEach(function(k){
if(k != "_id"){
keys.push(k);
}
})
emit(this.type,{"keys":keys});
}
reduce
功能:
type
个动物,请合并并返回unique
个键。Object
(uniqueKeys
)检查重复项,这会增加运行速度
时间,即使它占据一些记忆。查找是O(1)
。代码:
var reduce = function(key,values){
var uniqueKeys = {};
var result = [];
values.forEach(function(value){
value.keys.forEach(function(k){
if(!uniqueKeys[k]){
uniqueKeys[k] = 1;
result.push(k);
}
})
})
return {"keys":result};
}
调用Map-Reduce
:
db.collection.mapReduce(map,reduce,{out:"t1"});
汇总结果:
db.t1.aggregate([
{$project:{"_id":0,"animal":"$_id","keys":"$value.keys"}}
])
样本o / p:
{
"animal" : "lion",
"keys" : [
"name",
"height",
"weight",
"type"
]
}
{
"animal" : "zebra",
"keys" : [
"name",
"height",
"weight",
"type",
"zebraSpecific1",
"zebraSpecific2"
]
}
{
"animal" : "giraffe",
"keys" : [
"name",
"height",
"weight",
"type",
"giraffeSpecific1",
"giraffeSpecific2"
]
}