0

I have the following document structure

{
    _id: ..., 
    topics: [ ... ], 
    posts: [ {id: 1}, {id:2}, {id: 3}]
}

I would like to find all posts that match specific ids. E.g

[2,3]

I have tried this:

db.getCollection("data")
    .find({},{
        posts: {
            $elemMatch: {
                id: {
                    $in: [2, 3]
                    } 
                }
            }
        })

but it only return one post

{
    _id: ..., 
    posts: [ {id: 3} ]
}

I guess another way to go would be to just return all posts and filter then manually. Which one would have a better performance?

2
  • How does your requested result look? Commented Oct 7, 2022 at 10:17
  • the $elemMatch will return first single matching element, for your requirement you can use $filter operator and $in operator for condition checking. Commented Oct 7, 2022 at 10:18

1 Answer 1

2

If you want to achieve it via, MongoDB, you will have to achieve it via an aggregation pipeline, because you want to filter the posts array, which is done via the $filter operator, as suggested in the comments by @turivishal. Try this:

db.collection.aggregate([
  {
    "$addFields": {
      "posts": {
        "$filter": {
          "input": "$posts",
          "as": "item",
          "cond": {
            "$in": [
              "$$item.id",
              [
                1,
                2
              ]
            ]
          }
        }
      }
    }
  }
])

Playground link.

In terms of performance, usually, the filtering at the DB level is better because the operators are optimized as much as possible and also it reduces the data transferred as everything unnecessary is filtered out.

Sign up to request clarification or add additional context in comments.

2 Comments

Great stuff. Thank you. I guess if you wanted to optimise the query you could add in { "$project": { posts: 1} } to only return the posts field.
yes absolutely.

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.