Reputation: 8427
I have an array which looks like this
const posts = [{ _id: '1', viewsCount: 52 }, ...]
Which corresponds to mongodb documents in posts
collection
{
_id: '1',
title: 'some title',
body: '....',
}, ...
I want to perform an aggregation which would result in documents fetched from the posts
collection to have a viewsCount
field. I'm not sure how I should form my aggregation pipeline:
[
{ $match: {} },
{ $addFields: { viewsCount: ?? } }
]
UPDATE
So far the following code almost does the trick:
[
{ $match: {} },
{ $addFields: { viewsCount: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } } },
]
But viewsCount
in this case turns to be an object, so I guess I need to add $project
UPDATE
I've found out one possible solution which is to use $addFields
stage twice - overriding the first viewsCount
[
{ $match: {} },
{ $addFields: { viewsCount: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } } },
{ $addFields: { viewsCount: '$viewsCount.viewsCount' } }
]
But is there a better/more concise solution?
UPDATE
This pipeline actually works correct:
[
{ $match: {} },
{ $addFields: { viewsCount: { $arrayElemAt: [posts, { $indexOfArray: [ postsIds, '$_id' ] } ] } } },
{ $addFields: { viewsCount: '$viewsCount.viewsCount' } }
]
I have updated the second stage by replacing posts
with postsIds
Upvotes: 2
Views: 667
Reputation: 49985
To have a more concise solution (one-stage) you can use $let operator which lets you to define temporary variable that can be then used inside your expression, try:
db.posts.aggregate([
{ $addFields: {
viewsCount: {
$let: {
vars: { viewsCountObj: { $arrayElemAt: [posts, { $indexOfArray: [ posts, '$_id' ] } ] } },
in: "$$viewsCountObj.viewsCount"
}
} }
}
])
Upvotes: 2