我有一个看起来像这样的数组
const posts = [{ _id: '1', viewsCount: 52 }, ...]
与posts
集合中的mongodb文档相对应
{
_id: '1',
title: 'some title',
body: '....',
}, ...
我想执行一个聚合,这将导致从posts
集合中获取的文档具有一个viewsCount
字段。我不确定如何形成我的聚合管道:
[
{ $match: {} },
{ $addFields: { viewsCount: ?? } }
]
更新
到目前为止,以下代码几乎可以解决问题:
[
{ $match: {} },
{ $addFields: { viewsCount: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } } },
]
但是在这种情况下,viewsCount
变成了一个对象,所以我想我需要添加$project
更新
我发现了一个可能的解决方案,该方法是两次使用$addFields
阶段-覆盖第一个viewsCount
[
{ $match: {} },
{ $addFields: { viewsCount: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } } },
{ $addFields: { viewsCount: '$viewsCount.viewsCount' } }
]
但是有没有更好/更简洁的解决方案?
更新
此管道实际上正常工作:
[
{ $match: {} },
{ $addFields: { viewsCount: { $arrayElemAt: [posts, { $indexOfArray: [ postsIds, '$_id' ] } ] } } },
{ $addFields: { viewsCount: '$viewsCount.viewsCount' } }
]
我已经更新了第二阶段,将posts
替换为postsIds
答案 0 :(得分:1)
要获得更简洁的解决方案(一个阶段),可以使用$let运算符,该运算符可以定义可在表达式内部使用的临时变量,请尝试:
db.posts.aggregate([
{ $addFields: {
viewsCount: {
$let: {
vars: { viewsCountObj: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } },
in: "$$viewsCountObj.viewsCount"
}
} }
}
])