2013-09-18 4 views
14

Как я могу получить массив всех идентификаторов doc в MongoDB? Мне нужен только набор идентификаторов, но не содержимое документа.Как я могу получить все идентификаторы doc в MongoDB?

+7

'db.c.find ({}, {_ id: 1});' должен делать это – Sammaye

+0

то, что find() возвращено, является курсором, я все равно не видел все идентификаторы (но не документы , как cursor.toArray() делает) из возвращаемого курсора. – user2793120

+0

Поскольку MongoDB общается в BSON, я не думаю, что вы хотите, не исчерпывая курсор, а затем отфильтровывая значения. – Sammaye

ответ

27

Вы можете сделать это в оболочке Монго, вызвав map с курсором, как это:

var a = db.c.find({}, {_id:1}).map(function(item){ return item._id; }) 

Результатом является то, что a является массивом только в _id значений.

Способ работы в узле аналогичен.

(Это драйвер MongoDB Node v2.2 и Node v6.7.0)

db.collection('...') 
    .find(...) 
    .project({_id: 1}) 
    .map(x => x._id) 
    .toArray(); 

Не забывайте ставить mapперед темtoArray как это map НЕ функция JavaScript map, но это один обеспечивает MongoDB и он запускается внутри базы данных до возврата курсора.

3

Другой способ сделать это на Монго консоли может быть:

var arr=[] 
db.c.find({},{_id:1}).forEach(function(doc){arr.push(doc._id)}) 
printjson(arr) 

Надежда, что помогает !!!

Спасибо !!!

8

Один из способов - просто использовать API runCommand.

db.runCommand ({ distinct: "distinct", key: "_id" }) 

, который дает вам что-то вроде этого:

{ 
    "values" : [ 
     ObjectId("54cfcf93e2b8994c25077924"), 
     ObjectId("54d672d819f899c704b21ef4"), 
     ObjectId("54d6732319f899c704b21ef5"), 
     ObjectId("54d6732319f899c704b21ef6"), 
     ObjectId("54d6732319f899c704b21ef7"), 
     ObjectId("54d6732319f899c704b21ef8"), 
     ObjectId("54d6732319f899c704b21ef9") 
    ], 
    "stats" : { 
     "n" : 7, 
     "nscanned" : 7, 
     "nscannedObjects" : 0, 
     "timems" : 2, 
     "cursor" : "DistinctCursor" 
    }, 
    "ok" : 1 
} 

Однако, есть еще более красивый способ с использованием фактических distinct API:

var ids = db.distinct.distinct('_id', {}, {}); 

который просто дает вам массив идентификаторов:

[ 
    ObjectId("54cfcf93e2b8994c25077924"), 
    ObjectId("54d672d819f899c704b21ef4"), 
    ObjectId("54d6732319f899c704b21ef5"), 
    ObjectId("54d6732319f899c704b21ef6"), 
    ObjectId("54d6732319f899c704b21ef7"), 
    ObjectId("54d6732319f899c704b21ef8"), 
    ObjectId("54d6732319f899c704b21ef9") 
] 

Не уверен в первой версии, но последняя определенно поддерживается в драйвере Node.js (который я видел, как вы упомянули, что хотите использовать). Это будет выглядеть примерно так:

db.collection('c').distinct('_id', {}, {}, function (err, result) { 
    // result is your array of ids 
}) 
+0

не будет отличать лишнюю нагрузку на сервере esp, когда идентификаторы уже уникальны? – comiventor

+1

@comiventor это возможно ... но я полагаю, что OP только хочет сделать это на небольшом наборе данных, так что, вероятно, это не имеет большого значения. С другой стороны, это позволяет избежать циклического завершения всех результатов для их возврата в массив на клиенте. – whitfin

+0

это может/приведет к ошибке, например '' 'Команда с ошибкой 17217:« слишком большая, 16mb cap »на сервере''' на большом наборе данных – Watt

3

Я также задавался вопросом, как сделать это с водителем MongoDB Node.js, как @ user2793120. Кто-то еще сказал, что он должен перебирать результаты с., Который казался мне очень неэффективным. Я использовал MongoDB's aggregation вместо того, чтобы:

myCollection.aggregate([ 
      {$match: {ANY SEARCHING CRITERIA FOLLOWING $match'S RULES} }, 
      {$sort: {ANY SORTING CRITERIA, FOLLOWING $sort'S RULES}}, 
      {$group: {_id:null, ids: {$addToSet: "$_id"}}} 
    ]).exec() 

Сортировка фаза является необязательным. Совпадение также, если вы хотите, чтобы все коллекции были лишены. Если вы console.log результат, вы увидите что-то вроде:

[ { _id: null, ids: [ '56e05a832f3caaf218b57a90', '56e05a832f3caaf218b57a91', '56e05a832f3caaf218b57a92' ] } ] 

Затем просто использовать содержимое результата [0] .ids где-то в другом месте.

Ключевая часть здесь $group section.Вы должны определить значение null для _id (иначе произойдет слияние агрегации) и создать новое поле массива со всеми _ids. Если вы не возражаете против дублирования идентификаторов (в соответствии с вашими критериями поиска, используемыми в фазе $ match, и если вы группируете поле, отличное от _id, которое также имеет другой документ _id), вы можете использовать $push вместо $addToSet.

+0

Работает и на меня. – treecoder

Смежные вопросы