如何获取MongoDB中所有文档ID的数组?我只需要一组id,但不需要doc内容。
答案 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)
答案 7 :(得分:0)
上述示例之一对我有用,但稍作调整。当我尝试使用 Mongoose 模式时,我遗漏了第二个对象。
const idArray = await Model.distinct('_id', {}, function (err, result) {
// result is your array of ids
return result;
});