如何获取MongoDB中的所有文档ID?

时间:2013-09-18 20:41:24

标签: mongodb

如何获取MongoDB中所有文档ID的数组?我只需要一组id,但不需要doc内容。

8 个答案:

答案 0 :(得分:37)

您可以在Mongo shell中通过调用光标上的map来执行此操作:

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

结果是a只是_id值的数组。

它在Node中的工作方式与此类似。

(这是MongoDB节点驱动程序v2.2和节点v6.7.0

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

请务必先将map 放在 toArray之前,因为map不是JavaScript map函数,但它是MongoDB提供的函数并且它在返回游标之前在数据库中运行。

答案 1 :(得分:9)

一种方法是简单地使用runCommand API。

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', {}, {});

它只是为您提供了一系列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
})

答案 2 :(得分:4)

我也想知道如何使用MongoDB Node.JS驱动程序,如@ user2793120。其他人说他应该用.each迭代结果,这对我来说效率非常低。我改为使用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()

排序阶段是可选的。如果你想要所有的集合_ids,那么匹配一个。如果你使用console.log结果,你会看到类似的内容:

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

然后在其他地方使用result [0] .ids的内容。

这里的关键部分是$group section。您必须为_id定义null值(否则,聚合将崩溃),并创建一个包含所有_id的新数组字段。如果您不介意重复ID(根据$ match阶段中使用的搜索条件,并假设您正在对除_id之外的字段进行分组,并且还有另一个文档_id),则可以使用$push而不是$addToSet

答案 3 :(得分:3)

在mongo控制台上执行此操作的另一种方法可能是:

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

希望有所帮助!!!

感谢!!!

答案 4 :(得分:1)

我为此苦苦挣扎了很长时间,我之所以回答,是因为我有一个重要的提示。似乎很明显:

db.c.find({},{_id:1});

将是答案。

确实有效。它将找到前101个文档,然后应用程序将暂停。我没有让它继续下去。这既是在Java中使用MongoOperations,又是在Mongo命令行上。

我看了看mongo的日志,发现它正在对大量大文件进行colscan。我以为疯了,我正在投影总是被索引的_id,所以为什么要尝试colscan?

我不知道为什么要这么做,但是解决方案很简单:

db.c.find({},{_id:1}).hint(_id:1);

或使用Java:

query.withHint("{_id:1}");

然后,它可以使用流样式照常进行:

createStreamFromIterator(mongoOperations.stream(query, MortgageDocument.class)).
     map(MortgageDocument::getId).forEach(transformer);

Mongo可以做一些好事情,它也可能以真正令人困惑的方式卡住。到目前为止,至少这是我的经验。

答案 5 :(得分:1)

尝试使用聚合管道,如下所示:

db.collection.aggregate([
{ $match: { deletedAt: null }},
{ $group: { _id: "$_id"}}

])

此gona返回具有此结构的文档数组

_id: ObjectId("5fc98977fda32e3458c97edd")

答案 6 :(得分:0)

对于具有50+百万行的集合,我也有类似的要求。我尝试了很多方法。事实证明,获得ID的最快方法是仅对ID进行mongoexport。

答案 7 :(得分:0)

上述示例之一对我有用,但稍作调整。当我尝试使用 Mongoose 模式时,我遗漏了第二个对象。

const idArray = await Model.distinct('_id', {}, function (err, result) {
    // result is your array of ids
    return result;
});