我想获得MongoDB集合中所有键的名称。
例如,从这个:
db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] } );
db.things.insert( { hello : [] } );
我想获得唯一的键:
type, egg, hello
我想获得MongoDB集合中所有键的名称。
例如,从这个:
db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] } );
db.things.insert( { hello : [] } );
我想获得唯一的键:
type, egg, hello
当前回答
我知道我来晚了,但如果你想在python中快速找到所有键(甚至嵌套的键),你可以用递归函数来做:
def get_keys(dl, keys=None):
keys = keys or []
if isinstance(dl, dict):
keys += dl.keys()
list(map(lambda x: get_keys(x, keys), dl.values()))
elif isinstance(dl, list):
list(map(lambda x: get_keys(x, keys), dl))
return list(set(keys))
像这样使用它:
dl = db.things.find_one({})
get_keys(dl)
如果你的文件没有相同的密钥,你可以这样做:
dl = db.things.find({})
list(set(list(map(get_keys, dl))[0]))
但是这个解决方案肯定是可以优化的。
一般来说,这个解决方案基本上是解决在嵌套字典中查找键,所以这不是mongodb特定的。
其他回答
如果你的目标集合不是很大,你可以在mongo shell客户端下尝试:
var allKeys = {};
db.YOURCOLLECTION.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})});
allKeys;
我有一个更简单的工作…
你能做的是插入数据/文档到你的主集合“东西”,你必须在一个单独的集合中插入属性,让我们说“things_attributes”。
所以每次你插入"things"时,你确实会从"things_attributes"中得到该文档的值与你的新文档键的值进行比较,如果有任何新键存在,则将其追加到该文档中并再次重新插入它。
所以things_attributes只有一个唯一键的文档你可以通过findOne()很容易地得到
我扩展了Carlos LM的解决方案,使其更加详细。
一个模式的例子:
var schema = {
_id: 123,
id: 12,
t: 'title',
p: 4.5,
ls: [{
l: 'lemma',
p: {
pp: 8.9
}
},
{
l: 'lemma2',
p: {
pp: 8.3
}
}
]
};
在控制台输入:
var schemafy = function(schema, i, limit) {
var i = (typeof i !== 'undefined') ? i : 1;
var limit = (typeof limit !== 'undefined') ? limit : false;
var type = '';
var array = false;
for (key in schema) {
type = typeof schema[key];
array = (schema[key] instanceof Array) ? true : false;
if (type === 'object') {
print(Array(i).join(' ') + key+' <'+((array) ? 'array' : type)+'>:');
schemafy(schema[key], i+1, array);
} else {
print(Array(i).join(' ') + key+' <'+type+'>');
}
if (limit) {
break;
}
}
}
Run:
schemafy(db.collection.findOne());
输出
_id <number>
id <number>
t <string>
p <number>
ls <object>:
0 <object>:
l <string>
p <object>:
pp <number>
这对我来说很有效:
var arrayOfFieldNames = [];
var items = db.NAMECOLLECTION.find();
while(items.hasNext()) {
var item = items.next();
for(var index in item) {
arrayOfFieldNames[index] = index;
}
}
for (var index in arrayOfFieldNames) {
print(index);
}
使用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', ... ]