MongoDB使用$slice投影数组时如何仅返回目标数组字段
MongoDB查询:仅返回数组字段的指定切片(排除所有其他字段)
我有一个包含transactions数组字段的MongoDB文档,想要仅返回该数组的指定切片部分,不返回其他任何字段。但使用findOne的projection配置{ transactions: { $slice: [1, 2] } }时,会返回文档所有字段;加上_id:1的话,只会返回transactions和_id字段,还是达不到只返回切片后数组的要求。我已经找到用aggregate方法实现的方式,但想知道能不能用findOne的projection来实现这个需求?
示例数据
{ "_id": { "$oid": "641eca0f5687d0937c1041e2" }, "email": "example@gmail.com", "password": "$2b$10$MBuDAi3k7jTvckTsqQliQeWeg18JebLaDdltzMJwJ92bwP7i84Ee2", "emailVerified": true, "transactions": [ { "category": "t2", "subCategory": "bread", "type": "expense", "date": "2023-03-25T16:53:59.779Z", "amount": "1000", "id": { "$oid": "641f2727dc59db57eac9fa29" } }, { "category": "t3", "subCategory": "bread", "type": "expense", "date": "2023-03-25T16:54:04.243Z", "amount": "1000", "id": { "$oid": "641f272cdc59db57eac9fa2a" } }, { "category": "t4", "subCategory": "bread", "type": "expense", "date": "2023-03-25T16:54:08.780Z", "amount": "1000", "id": { "$oid": "641f2730dc59db57eac9fa2b" } } ] }
原findOne查询代码
const result = await users.findOne( { _id: new ObjectId(id) }, { projection: { transactions: { $slice: [1, 2] } }} );
已实现的aggregate方案
目前已经通过aggregate方法实现需求,代码如下:
const aggCursor = users.aggregate<TransactionsPagRes>([ { $match: { _id: new ObjectId(id) }, }, { $project: { _id: 0, transactions: { $slice: ['$transactions', 1, 2] }, }, }, ]); const result = await aggCursor.next();
关于findOne的projection实现说明
在MongoDB的find/findOne查询中,用projection配合$slice无法直接实现“仅返回切片后的transactions数组”的需求,原因如下:
- 默认规则下,
_id字段会被强制返回,除非显式设置_id: 0 - 即使设置
{ transactions: { $slice: [1,2] }, _id: 0 },MongoDB仍会返回文档的所有其他字段(这是MongoDB处理数组操作符时的特殊逻辑)
如果一定要用findOne,只能先拿到包含transactions切片和_id的结果,再手动提取transactions字段;更简洁的方式还是使用上述的aggregate方案。
内容的提问来源于stack exchange,提问作者Amir
相关产品推荐
相关产品推荐

