聚合:将字段从另一个对象添加到mongo文档

时间:2019-02-19 14:05:42

标签: mongodb

我有一个看起来像这样的数组

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

1 个答案:

答案 0 :(得分:1)

要获得更简洁的解决方案(一个阶段),可以使用$let运算符,该运算符可以定义可在表达式内部使用的临时变量,请尝试:

db.posts.aggregate([
    { $addFields: { 
        viewsCount: {
            $let: {
                vars: { viewsCountObj: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } },
                in: "$$viewsCountObj.viewsCount"
            }
        } }
    }
])
相关问题