Получить имена всех ключей в коллекции - PullRequest
294 голосов
/ 19 февраля 2010

Я хотел бы получить имена всех ключей в коллекции MongoDB.

Например, из этого:

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

Я бы хотел получить уникальные ключи:

type, egg, hello

Ответы [ 19 ]

317 голосов
/ 22 февраля 2010

Вы можете сделать это с помощью 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"
})

Затем запустите на результирующей коллекции отчетливо, чтобы найти все ключи:

db[mr.result].distinct("_id")
["foo", "bar", "baz", "_id", ...]
191 голосов
/ 28 апреля 2012

Используя ответ Кристины в качестве вдохновения, я создал инструмент с открытым исходным кодом под названием Variety, который делает именно это: https://github.com/variety/variety

46 голосов
/ 23 апреля 2017

Вы можете использовать агрегацию с новой $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"}}
])
19 голосов
/ 06 марта 2014

Попробуйте это:

doc=db.thinks.findOne();
for (key in doc) print(key);
14 голосов
/ 26 декабря 2016

Если ваша целевая коллекция не слишком велика, вы можете попробовать это в клиенте оболочки mongo:

var allKeys = {};

db.YOURCOLLECTION.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})});

allKeys;
10 голосов
/ 11 августа 2014

Использование 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()
)
7 голосов
/ 25 апреля 2014

Вот пример, сработавший в 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']
5 голосов
/ 05 января 2018

Очищенный и многоразовый раствор с использованием пимонго:

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', ... ]
3 голосов
/ 02 октября 2018

Если вы используете 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" }
  }}
])

Вот рабочий пример

2 голосов
/ 16 апреля 2019

Удивительно, но здесь ни у кого нет ответа с помощью простой логики javascript и Set для автоматической фильтрации значений дубликатов, простой пример для mongo shell , как показано ниже:

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 .

...