我如何在MongoDB中获得所有文档ID的数组?我只需要一组ID,而不需要文档内容。
r1zhe5dt1#
你可以在Mongo shell中通过在游标上调用map来实现这一点,如下所示:
map
var a = db.c.find({}, {_id:1}).map(function(item){ return item._id; })
结果是a是一个只有_id值的数组。它在Node中的工作方式类似。(This是MongoDB节点驱动程序v2.2和节点v6.7.0)
a
_id
v2.2
v6.7.0
db.collection('...') .find(...) .project( {_id: 1} ) .map(x => x._id) .toArray();
请记住将map放在toArray之前,因为这个map不是JavaScript map函数,而是MongoDB提供的函数,它在返回游标之前在数据库中运行。
toArray
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还有一种更好的方法:
distinct
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 })
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。
bybem2ql4#
在mongo控制台上执行此操作的另一种方法可能是:
var arr=[] db.c.find({},{_id:1}).forEach(function(doc){arr.push(doc._id)}) printjson(arr)
希望能有所帮助!谢谢!!!
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可以做一些好的事情,但它也可能会以令人困惑的方式陷入困境,至少这是我目前的经验。
0ve6wy6x6#
尝试使用agregation管道,如下所示:
db.collection.aggregate([ { $match: { deletedAt: null }}, { $group: { _id: "$_id"}}
])这个gona返回一个文档数组,结构如下
_id: ObjectId("5fc98977fda32e3458c97edd")
eulz3vhy7#
我有一个类似的要求,要为一个有5000多万行的集合获取id。我尝试了很多方法。最快的获取id的方法是只使用id执行mongoexport。
txu3uszq8#
上面的例子中有一个对我来说很有效,只是做了一个小的调整。我省略了第二个对象,因为我试图在Mongoose模式中使用。
const idArray = await Model.distinct('_id', {}, function (err, result) { // result is your array of ids return result; });
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()
9条答案
按热度按时间r1zhe5dt1#
你可以在Mongo shell中通过在游标上调用
map
来实现这一点,如下所示:结果是
a
是一个只有_id
值的数组。它在Node中的工作方式类似。
(This是MongoDB节点驱动程序
v2.2
和节点v6.7.0
)请记住将
map
放在toArray
之前,因为这个map
不是JavaScriptmap
函数,而是MongoDB提供的函数,它在返回游标之前在数据库中运行。5lhxktic2#
一种方法是简单地使用runCommand API。
它会给你这样的东西:
然而,使用实际的
distinct
API还有一种更好的方法:它只是给你一个id数组:
不确定第一个版本,但Node.js驱动程序肯定支持后者(我看到你提到你想使用)。看起来像这样:
gcxthw6b3#
我也想知道如何使用MongoDB Node.JS驱动程序来实现这一点,比如@user2793120。其他人说他应该使用.each来迭代结果,这对我来说似乎效率很低。我使用了MongoDB's aggregation:
排序阶段是可选的。如果你想要所有集合的_id,匹配阶段也是可选的。如果你console.log结果,你会看到如下内容:
然后在其他地方使用result[0].ids的内容。
这里的关键部分是$group section。(否则,聚合会崩溃),并创建一个包含所有_id的新数组字段。(根据$match阶段中使用的搜索条件,并假设您正在对除_id之外的字段进行分组,该字段还具有另一个document _id),可以使用$push代替$addToSet。
bybem2ql4#
在mongo控制台上执行此操作的另一种方法可能是:
希望能有所帮助!
谢谢!!!
jw5wzhpr5#
我挣扎了很长一段时间,我回答这个问题,因为我得到了一个重要的提示。很明显:
就是答案
它工作了,某种程度上。它会找到前101个文档,然后应用程序会暂停。我没有让它继续下去。这既在Java中使用MongoOperations,也在Mongo命令行上。
我查看了mongo日志,看到它正在对一个大文档集合进行colscan,我想,疯了,我正在投射总是被索引的_id,为什么它要尝试colscan?
我不知道为什么会这样,但答案很简单:
在Java中:
然后,它可以正常沿着,使用流样式:
Mongo可以做一些好的事情,但它也可能会以令人困惑的方式陷入困境,至少这是我目前的经验。
0ve6wy6x6#
尝试使用agregation管道,如下所示:
])
这个gona返回一个文档数组,结构如下
eulz3vhy7#
我有一个类似的要求,要为一个有5000多万行的集合获取id。我尝试了很多方法。最快的获取id的方法是只使用id执行mongoexport。
txu3uszq8#
上面的例子中有一个对我来说很有效,只是做了一个小的调整。我省略了第二个对象,因为我试图在Mongoose模式中使用。
uyto3xhc9#
Kotlin和Spring Data 的解决方案
一个简单的解决方案,获取所有文档并从中获取ID:
一个优化的解决方案,使用MongoDB Aggregation功能只获取ID: