vaibhav0228
vaibhav0228

Reputation: 49

Mongo DB to filter a Document if the field of an array has same value across all elements using mongo java driver

I need to fetch the document from the db, data is as below

{
   "systemName": "ABC",
    "systemUsageAttrs" : [
                          {
                           "cpuUsage": 30,
                           "memUsage": 40,
                           "isActive": false
                           },
                           {
                           "cpuUsage": 88.2,
                           "memUsage": 33.5,
                           "isActive": false
                           }
                         ]
},
{
   "systemName": "DEF",
    "systemUsageAttrs" : [
                          {
                           "cpuUsage": 30,
                           "memUsage": 40,
                           "isActive": false
                           },
                           {
                           "cpuUsage": 88.2,
                           "memUsage": 33.5,
                           "isActive": true
                           }
                         ]
},
{
   "systemName": "GHI",
    "systemUsageAttrs" : [
                          {
                           "cpuUsage": 30,
                           "memUsage": 40,
                           "isActive": true
                           },
                           {
                           "cpuUsage": 88.2,
                           "memUsage": 33.5,
                           "isActive": true
                           }
                         ]
}

I have used below piece of code, but it returns 2 documents instead of one.

List<Document> systemDetailsAL = sysUsageDetailsColl.aggregate(
                asList(
                        unwind("$systemUsageAttrs"),
                        match(eq("systemUsageAttrs.isActive",false)),
                        group("$_id", Accumulators.first("systemName","$systemName"),
                                Accumulators.push("systemUsageAttrs", "$systemUsageAttrs")),
                        project(Projections.fields(Projections.excludeId()))
                        
                        )
                ).into(new ArrayList<Document>());

Above code also provides the document which has isActive:false for one of the elements in the array.

Expected output is Document with systemName: ABC, since it has isActive:false in all the elements of array.

Any help/pointers appreciated.

Upvotes: 2

Views: 636

Answers (1)

Gibbs
Gibbs

Reputation: 22974

Play

db.collection.find({
  "systemUsageAttrs": {
    "$not": {
      "$elemMatch": {
        "isActive": {
          $nin: [
            false
          ]
        }
      }
    }
  }
})

$not excludes documents which are identified by $elemMatch where value is not false.

  1. $elemMatch identifies documents where isActive not in false
  2. $not excludes that documents.

You can convert this query to java compatible.

Problem with the code i.e query used:

  1. You are doing unwind
  2. Then finding all docs - it returns the first sub doc of second document
  3. You are grouping again
  4. It will have the second document as well because it is part of the previous pipeline.

Upvotes: 1

Related Questions