我想获取MongoDB集合中所有键的名称.
例如,从这个:
db.things.insert( { type : ['dog', 'cat'] } ); db.things.insert( { egg : ['cat'] } ); db.things.insert( { type : [] } ); db.things.insert( { hello : [] } );
我想得到独特的钥匙:
type, egg, hello
kristina.. 323
您可以使用MapReduce执行此操作:
mr = db.runCommand({ "mapreduce" : "my_collection", "map" : function() { for (var key in this) { emit(key, null); } }, "reduce" : function(key, stuff) { return null; }, "out": "my_collection" + "_keys" })
然后在生成的集合上运行distinct,以便找到所有键:
db[mr.result].distinct("_id") ["foo", "bar", "baz", "_id", ...]
这可能是显而易见的,但是如果你想得到一个子文档中所有唯一键的列表,只需修改这一行:`for(var key in this.first_level.second_level.nth_level){emit(key,null); }` (6认同)
我知道这是一个老线程,但我似乎有类似的需求.我正在使用nodejs mongodb本机驱动程序.由此产生的临时收集似乎总是空着.我正在集合类中使用mapreduce函数.这不可能吗? (3认同)
嗨,您好!我刚刚发布了一个关于这个问题的后续问题,询问如何使这个代码片段工作,即使是位于数据结构更深层次的密钥(http://stackoverflow.com/questions/2997004/using-map-reduce-for -mapping最性质-IN-A-集合). (2认同)
小智.. 196
以Kristina的答案为灵感,我创建了一个名为Variety的开源工具,它正是这样做的:https://github.com/variety/variety
您可以使用MapReduce执行此操作:
mr = db.runCommand({ "mapreduce" : "my_collection", "map" : function() { for (var key in this) { emit(key, null); } }, "reduce" : function(key, stuff) { return null; }, "out": "my_collection" + "_keys" })
然后在生成的集合上运行distinct,以便找到所有键:
db[mr.result].distinct("_id") ["foo", "bar", "baz", "_id", ...]
以Kristina的答案为灵感,我创建了一个名为Variety的开源工具,它正是这样做的:https://github.com/variety/variety
您可以使用聚集新$objectToArrray
的3.4.4
版本所有顶级密钥值对转换成文件阵列,然后$unwind
与$group
用$addToSet
得到跨越整个集合不同的键.
$$ROOT
用于引用顶级文档.
db.things.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$unwind":"$arrayofkeyvalue"}, {"$group":{"_id":null,"allkeys":{"$addToSet":"$arrayofkeyvalue.k"}}} ])
您可以使用以下查询来获取单个文档中的键.
db.things.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$project":{"keys":"$arrayofkeyvalue.k"}} ])
试试这个:
doc=db.thinks.findOne(); for (key in doc) print(key);
如果您的目标集合不是太大,您可以在mongo shell客户端下尝试:
var allKeys = {}; db.YOURCOLLECTION.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})}); allKeys;
使用python.返回集合中所有顶级键的集合:
#Using pymongo and connection named 'db' reduce( lambda all_keys, rec_keys: all_keys | set(rec_keys), map(lambda d: d.keys(), db.things.find()), set() )
使用pymongo清理并重用的解决方案:
from pymongo import MongoClient from bson import Code def get_keys(db, collection): client = MongoClient() db = client[db] map = Code("function() { for (var key in this) { emit(key, null); } }") reduce = Code("function(key, stuff) { return null; }") result = db[collection].map_reduce(map, reduce, "myresults") return result.distinct('_id')
用法:
get_keys('dbname', 'collection') >> ['key1', 'key2', ... ]
以下是在Python中使用的示例:此示例以内联方式返回结果.
from pymongo import MongoClient from bson.code import Code mapper = Code(""" function() { for (var key in this) { emit(key, null); } } """) reducer = Code(""" function(key, stuff) { return null; } """) distinctThingFields = db.things.map_reduce(mapper, reducer , out = {'inline' : 1} , full_response = True) ## do something with distinctThingFields['results']
如果您使用的是mongodb 3.4.4及更高版本,则可以使用$objectToArray
和$group
聚合来使用以下聚合
db.collection.aggregate([ { "$project": { "data": { "$objectToArray": "$$ROOT" } }}, { "$project": { "data": "$data.k" }}, { "$unwind": "$data" }, { "$group": { "_id": null, "keys": { "$addToSet": "$data" } }} ])
这是工作示例