我想获得MongoDB集合中所有键的名称。

例如,从这个:

db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] } );
db.things.insert( { hello : []  } );

我想获得唯一的键:

type, egg, hello

当前回答

我很惊讶,这里没有人使用简单的javascript和Set逻辑来自动过滤重复的值,下面是mongo shellas的简单例子:

var allKeys = new Set()
db.collectionName.find().forEach( function (o) {for (key in o ) allKeys.add(key)})
for(let key of allKeys) print(key)

这将打印集合名称:collectionName中所有可能的惟一键。

其他回答

我有一个更简单的工作…

你能做的是插入数据/文档到你的主集合“东西”,你必须在一个单独的集合中插入属性,让我们说“things_attributes”。

所以每次你插入"things"时,你确实会从"things_attributes"中得到该文档的值与你的新文档键的值进行比较,如果有任何新键存在,则将其追加到该文档中并再次重新插入它。

所以things_attributes只有一个唯一键的文档你可以通过findOne()很容易地得到

使用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()
)

我知道这个问题已经10年了,但是c#没有解决方案,我花了好几个小时才弄清楚。我正在使用。net驱动程序和系统。Linq返回键的列表。

var map = new BsonJavaScript("function() { for (var key in this) { emit(key, null); } }");
var reduce = new BsonJavaScript("function(key, stuff) { return null; }");
var options = new MapReduceOptions<BsonDocument, BsonDocument>();
var result = await collection.MapReduceAsync(map, reduce, options);
var list = result.ToEnumerable().Select(item => item["_id"].ToString());

我知道我来晚了,但如果你想在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特定的。

使用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', ... ]