2

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.

Gibbs
  • 21,904
  • 13
  • 74
  • 138

1 Answers1

1

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.
Gibbs
  • 21,904
  • 13
  • 74
  • 138
  • @prasad_ any pointers how to write Filters for the above answer. Tried below code, but doesnt seem to work ` sysUsageDetailsColl.find(Filters.not(Filters.elemMatch(systemUsageAttrs.$.isActive, Filters.nin("systemUsageAttrs.$.isActive", false)))).projection(Projections.excludeId()) .into(new ArrayList()); ` – vaibhav0228 Jul 14 '20 at 09:59
  • @vaibhav0228 Were you able to achieve this? – Gibbs Jul 19 '20 at 09:00
  • nope, i did not got the java solution for the answer u provided. – vaibhav0228 Jul 19 '20 at 09:17
  • Were you stuck at something? – Gibbs Jul 19 '20 at 09:28
  • cant say stuck, but i was not able to write corresponding filters in java. – vaibhav0228 Jul 20 '20 at 08:06