blueseal
blueseal

Reputation: 2908

How to filter a collection in Mongodb

Let's say I have three documents in a collection, like so:

[
  {"_id": "101", parts: ["a", "b"]},
  {"_id": "102", parts: ["a", "c"]},
  {"_id": "103", parts: ["a", "z"]},
]

what is the query I have to write so that if I input ["a","b","c"] (i.e. all items in parts field value in each doc should be present in ["a","b","c"]) will output:

[
  {"_id": "101", parts: ["a", "b"]},
  {"_id": "102", parts: ["a", "c"]}
]

is this even possible? any idea?

Upvotes: 0

Views: 4073

Answers (2)

blueseal
blueseal

Reputation: 2908

Thanks to @prasad_. I have tried to come up with a solution which is similar to what I wanted. I have used $setDifference here.

db.collection.aggregate([
  {
    $project: {
      diff: {
        $setDifference: [
          "$parts",
          [
            "a",
            "b",
            "c"
          ]
        ]
      },
      document: "$$ROOT"
    }
  },
  {
    $match: {
      "diff": {
        $eq: []
      }
    }
  },
  {
    $project: {
      "diff": 0
    }
  },
  
])

output:

[
  {
    "_id": "101",
    "document": {
      "_id": "101",
      "parts": [
        "a",
        "b"
      ]
    }
  },
  {
    "_id": "102",
    "document": {
      "_id": "102",
      "parts": [
        "a",
        "c"
      ]
    }
  }
]

Mongo Playground

Upvotes: 0

Cuong Le Ngoc
Cuong Le Ngoc

Reputation: 11975

Below solution may not be the best but it works. The idea is finding all documents that has no items in parts outside the input array. It can be done with combination of $not, $elemMatch and $nin:

db.collection.find({
  parts: {
    $not: {
      "$elemMatch": {
        $nin: ["a", "b", "c"]
      }
    }
  }
})

Mongo Playground

Upvotes: 1

Related Questions