当revisions
是一个对象(键为entryId)时,我有一个正在运行的聚合调用。
await Project.aggregate([
{ $limit: 1 },
{ $match: { _id: ObjectId(projectId) } },
{
$project: {
limits: 1,
revisions: { $slice: [`$revisions.${entryId}.${languageId}`, startIndex, PageSize] },
totalRevisions: {
$size: { $ifNull: [`$revisions.${entryId}.${languageId}`, []] },
},
},
},
]);
现在,我将revisions
转换为其中包含entryId的数组,我不确定如何获得相同的结果。我尝试过:
await Project.aggregate([
{ $limit: 1 },
{
$match: {
_id: ObjectId(projectId),
'revisions.entryId': ObjectId(entryId),
},
},
{
$project: {
limits: 1,
revisions: { $slice: [`$revisions.$.${languageId}`, startIndex, PageSize] },
totalRevisions: {
$size: { $ifNull: [`$revisions.$.${languageId}`, []] },
},
},
},
]);
但是我得到了错误:
MongoError:FieldPath字段名称不能以“ $”开头。
如何对数组中的项目使用$slice
和$ifNull
?谢谢
示例文档:
{
"revisions" : [
{
"entryId" : ObjectId("5bbf8813c272e05171463bc4"),
"5bbe76c6d3fb1a4f143f8304" : [
{
"authorId" : ObjectId("5b1c5384d75d9f3b0eb65c2a"),
"revisionId" : ObjectId("5bbf8813c272e05171463bc7"),
"updated" : "2018-10-11T17:27:47.842Z",
"value" : "County"
}
]
}
]
}
答案 0 :(得分:1)
管道阶段的顺序在这里确实很重要。在$limit
之前使用$match
时,它将过滤$limit
阶段中找到的单个文档中的数据。
如果您将在$match
之前使用$limit
,那么它将从数据库内的所有集合中过滤文档,并在$limit
阶段抛出单个文档。
之后,您可以尝试以下汇总
db.collection.aggregate([
{ "$match": {
"_id": ObjectId(projectId),
"revisions.entryId": ObjectId(entryId)
}},
{
"$project": {
"revisions": {
"$map": {
"input": "$revisions",
"in": {
"$arrayToObject": {
"$map": {
"input": {
"$filter": {
"input": { "$objectToArray": "$$this" },
"as": "ee",
"cond": { "$eq": ["$$ee.k", "5bbe76c6d3fb1a4f143f8304"] }
}
},
"as": "dd",
"in": {
"k": "$$dd.k",
"v": { "$slice": [startIndex, 1 ] }
}
}
}
}
}
},
"totalRevisions": {
"$arrayElemAt": [
{
"$map": {
"input": "$revisions",
"in": {
"$size": {
"$map": {
"input": {
"$filter": {
"input": { "$objectToArray": "$$this" },
"as": "ee",
"cond": { "$eq": ["$$ee.k", "5bbe76c6d3fb1a4f143f8304"] }
}
},
"as": "dd",
"in": {
"k": "$$dd.k",
"v": { "$slice": [startIndex, 1] }
}
}
}
}
}
},
0
]
}
}
}
])
但是,如果您刚开始您的项目,那么我强烈建议您不要使用这种结构,因为您的嵌套数组键是动态的,并且使用动态键总是像在裸电线上玩一样。