2

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

1 Answer 1

2

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"
            }
        } }
    }
])
Sign up to request clarification or add additional context in comments.

3 Comments

seems like your solution does not solve the problem (as well as mine). Aggregated documents all have same viewsCount value
I guess the problem steams from $indexOfArray
You can try { $indexOfArray: [ posts.map(p => p._id), '$_id' ] }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.