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

uujelgoq  于 2023-04-05  发布在  Go
关注(0)|答案(9)|浏览(200)

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

r1zhe5dt

r1zhe5dt1#

你可以在Mongo shell中通过在游标上调用map来实现这一点,如下所示:

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

结果是a是一个只有_id值的数组。
它在Node中的工作方式类似。
(This是MongoDB节点驱动程序v2.2和节点v6.7.0

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

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

5lhxktic

5lhxktic2#

一种方法是简单地使用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
})
gcxthw6b

gcxthw6b3#

我也想知道如何使用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()

排序阶段是可选的。如果你想要所有集合的_id,匹配阶段也是可选的。如果你console.log结果,你会看到如下内容:

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

然后在其他地方使用result[0].ids的内容。
这里的关键部分是$group section。(否则,聚合会崩溃),并创建一个包含所有_id的新数组字段。(根据$match阶段中使用的搜索条件,并假设您正在对除_id之外的字段进行分组,该字段还具有另一个document _id),可以使用$push代替$addToSet

bybem2ql

bybem2ql4#

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

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

希望能有所帮助!
谢谢!!!

jw5wzhpr

jw5wzhpr5#

我挣扎了很长一段时间,我回答这个问题,因为我得到了一个重要的提示。很明显:

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可以做一些好的事情,但它也可能会以令人困惑的方式陷入困境,至少这是我目前的经验。

0ve6wy6x

0ve6wy6x6#

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

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

])
这个gona返回一个文档数组,结构如下

_id: ObjectId("5fc98977fda32e3458c97edd")
eulz3vhy

eulz3vhy7#

我有一个类似的要求,要为一个有5000多万行的集合获取id。我尝试了很多方法。最快的获取id的方法是只使用id执行mongoexport。

txu3uszq

txu3uszq8#

上面的例子中有一个对我来说很有效,只是做了一个小的调整。我省略了第二个对象,因为我试图在Mongoose模式中使用。

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

uyto3xhc9#

Kotlin和Spring Data 的解决方案
一个简单的解决方案,获取所有文档并从中获取ID:

// Defining the Repository.
@Repository
interface MyRepository : MongoRepository<MyDocument, String> {
}

// Fetching the IDs.
val ids: List<String> = myRepository.findAll().mapNotNull { it._id }

一个优化的解决方案,使用MongoDB Aggregation功能只获取ID:

// Defining the Repository.
@Repository
interface MyRepository : MongoRepository<MyDocument, String> {
    @Aggregation(pipeline = [
        "{ '\$project': { '_id': 1 } }"
    ])
    fun findAllIds(): List<String>
}

// Fetching the IDs.
val ids: List<String> = myRepository.findAllIds()

相关问题