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

如何在MongoDB中获取所有文档ID?,mongodb,Mongodb,如何获取MongoDB中所有文档ID的数组?我只需要一组ID,但不需要文档内容。您可以在Mongo shell中通过如下方式调用光标来完成此操作: { "values" : [ ObjectId("54cfcf93e2b8994c25077924"), ObjectId("54d672d819f899c704b21ef4"), ObjectId("54d6732319f899c704b21ef5"), ObjectId("5

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

您可以在Mongo shell中通过如下方式调用光标来完成此操作:

{
    "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
}
db.collection('c').distinct('_id', {}, {}, function (err, result) {
    // result is your array of ids
})
db.collection.aggregate([
{ $match: { deletedAt: null }},
{ $group: { _id: "$_id"}}
var a=db.c.find({},{u-id:1}).map(函数(项){return-item.\u-id;})
结果是
a
只是
\u id
值的数组

它在节点中的工作方式类似

(这是MongoDB节点驱动程序
v2.2
,以及节点
v6.7.0


请记住将
map
放在
toArray
之前,因为这
map
不是JavaScript
map
函数,而是MongoDB提供的函数,它在返回光标之前在数据库中运行。

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

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


谢谢

一种方法是简单地使用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
}
db.collection('c').distinct('_id', {}, {}, function (err, result) {
    // result is your array of ids
})
db.collection.aggregate([
{ $match: { deletedAt: null }},
{ $group: { _id: "$_id"}}
但是,使用实际的
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驱动程序中肯定支持后者(我看到你提到你想要使用它)。看起来是这样的:

{
    "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
}
db.collection('c').distinct('_id', {}, {}, function (err, result) {
    // result is your array of ids
})
db.collection.aggregate([
{ $match: { deletedAt: null }},
{ $group: { _id: "$_id"}}

我还想知道如何使用MongoDB Node.JS驱动程序来实现这一点,比如@user2793120。还有人说他应该用.来反复检查结果,每个结果对我来说都是非常低效的。我改为:

排序阶段是可选的。如果您想要所有集合的_id,那么还需要匹配一个。如果您使用console.log记录结果,您将看到如下内容:

    [ { _id: null, ids: [ '56e05a832f3caaf218b57a90', '56e05a832f3caaf218b57a91', '56e05a832f3caaf218b57a92' ] } ]
然后只需在其他地方使用result[0].ids的内容


这里的关键部分是。必须为_id定义null值(否则,聚合将崩溃),并使用所有_id创建一个新的数组字段。如果您不介意使用重复的id(根据$match阶段使用的搜索条件,并假设您分组的字段不是_id,它也有另一个文档_id),您可以使用代替。

我一直在努力解决这个问题,我回答这个问题是因为我得到了一个重要的提示。显然:

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可以做一些好事,它也可以陷入非常混乱的状态。至少到目前为止,这是我的经验。

对于5000多万行的集合,我也有类似的要求。我尝试了很多方法。获取ID的最快方法是只使用ID进行mongoexport。

尝试使用一个拒绝管道,如下所示:

{
    "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
}
db.collection('c').distinct('_id', {}, {}, function (err, result) {
    // result is your array of ids
})
db.collection.aggregate([
{ $match: { deletedAt: null }},
{ $group: { _id: "$_id"}}
])

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

_id: ObjectId("5fc98977fda32e3458c97edd")

上面的一个例子对我很有用,只是做了一点小小的调整。当我尝试使用Mongoose模式时,我省略了第二个对象

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

db.c.find({},{u id:1})应该这样做find()返回的是一个游标,我没有看到检索所有ID的方法(但不是像cursor.toArray()那样检索文档)从返回的游标。由于MongoDB在BSON中通信,我认为如果不耗尽游标,然后过滤掉值,就不可能实现您想要的功能。当ID已经唯一时,不会在服务器esp上施加不必要的负载?@comiventor这是可能的。。。但我想OP只是想在一个小数据集上做这件事,所以这可能没什么大不了的。另一方面,它避免了必须循环所有结果以将它们缓冲回客户端上的数组中。这可能/将导致类似于
命令失败的错误,错误为17217:服务器上的“distinct too big,16mb cap”
在大数据集上