How to extract data if array contains required data

I have documents like this:

_id:shubham
hobbies [2 elements]
  [0] {2 fields}
 Type : Drawing
 Members: 1
  [1] {2 fields}
 Type : Cricket
 Members: 11

 _id:anant
hobbies [2 elements]
  [0] {2 fields}
 Type : Drawing
 Members: 1

  _id:nipoon
hobbies [2 elements]
  [0] {2 fields}
 Type : Drawing
 Members: 1
  [1] {2 fields}
 Type : Cricket
 Members: 11

I want to extract data which as both Drawing and Cricket as hobbies and eliminate if not having both.

In above case I want all data of _id: shubham and _id: nipoon and eliminate _id: anant.

Could you please provide your sample data as well formed JSON documents?

This way we can just cut-n-paste the documents directly in our installation. This will help us help you faster.

2 Likes

Hello : )

I think you ask how to select documents,only if an array contains specific members.
Here get only the documents that the hobbies array has as member the “Drawing” and “Cricket”

I inserted this data


[
  {
    "_id": "shubham",
    "hobbies": [
      "Drawing",
      "Cricket"
    ],
    "members": 11
  },
  {
    "_id": "anant",
    "hobbies": [
      "Drawing",
      "Dance"
    ],
    "members": 1
  },
  {
    "_id": "nipoon",
    "hobbies": [
      "Cook",
      "Dance"
    ],
    "members": 10
  }
]

And i got

{
  "_id": "shubham",
  "hobbies": [
    "Drawing",
    "Cricket"
  ],
  "members": 11
}

You can do this with $in operator or with $setIsSubset,you can test the perfomance and choose.
I give you the mongo command,take only the pipeline and use it with any driver.

{
  "aggregate": "testcoll",
  "pipeline": [
    {
      "$match": {
        "$expr": {
          "$and": [
            {
              "$in": [
                "Cricket",
                "$hobbies"
              ]
            },
            {
              "$in": [
                "Drawing",
                "$hobbies"
              ]
            }
          ]
        }
      }
    }
  ],
  "maxTimeMS": 0,
  "cursor": {}
}
{
  "aggregate": "testcoll",
  "pipeline": [
    {
      "$match": {
        "$expr": {
          "$setIsSubset": [
            [
              "Cricket",
              "Drawing"
            ],
            "$hobbies"
          ]
        }
      }
    }
  ],
  "maxTimeMS": 0,
  "cursor": {}
}

I think I have a simpler version with the $all array operator:

> db.col.find({hobbies: {$all: ["Cricket", "Drawing"]}})
{ "_id" : "shubham", "hobbies" : [ "Drawing", "Cricket" ], "members" : 11 }

Cheers,
Maxime.