在我的数据中,其中一个字段是一个数组,我只想返回该数组的一部分,仅此而已,没有更多的字段。但是当我在投影中使用$slice
时,它将返回所有的字段。
我的数据:
{
"_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"
}
}
]
}
我在node.js中的查询是这样的:
const result = await users.findOne(
{ _id: new ObjectId(id) },
{ projection: { transactions: { $slice: [1, 2] } }}
);
通过这个投影,我得到了结果中的所有字段。如果我将投影更改为{ transactions: { $slice: [1, 2] }, _id: 1 }
,它将只返回transactions
和_id
。但我只想要交易。
更新日期:
经过一番研究,我发现这对于aggregate
方法是可能的。聚合所做的基本上是基于管道上的前一阶段重新创建投影。但我仍然不知道projection
on findOne
方法。
const aggCursor = users.aggregate<TransactionsPagRes>([
{
$match: { _id: new ObjectId(id) },
},
{
$project: {
_id: 0,
transactions: { $slice: ['$transactions', 1, 2] },
},
},
]);
const result = await aggCursor.next();
2条答案
按热度按时间bnl4lu3b1#
如果你不介意返回
transactions
,你需要像这样把其他你不需要的属性列入黑名单:它将返回如下信息:
如果你想拥有一个用户事务的平面数组,$unwind聚合是一种方法:
退货:
MongoDB Playground .
hfsqlsce2#
使用
$slice
操作符似乎并不像投影那样排除其他字段,这似乎是MongoDB中的意外行为。有几个选择可以获得您想要的行为:
1.修改传递给查找的投影
由于投影永远不会隐式地排除_id,因此无论如何都需要修改它。要排除所有其他字段,要么显式地排除每个字段,要么包含实际不存在的字段。
Playground
1.使用聚合管道您仍然需要显式排除_id,但不需要引用不存在的字段来排除其他字段
Playground