Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Mongodb get specific properties in the aggregate result from a document

I’m a little lost on how to use aggregate to obtain very specific type of results.
My db documents have the following format

{
  _id: 122434
  houseDetails: {
     hasBedroom: {
       flag: true,
     },
     hasKitchen: {
       flag: false
     },
     hasBalcony: {
       flag: false
     },
     hasFoyer: {
       flag: true
     },
  }
}

(This is a basic example of the structure of the document, the details are different)

I’m trying to query all the documents where the nested houseDetails properties are true.
So in the end I’d like the result to look like

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
  _id: 122434,
  houseDetails: [hasBedroom, hasFoyer]
}

I can use $match to find all the documents where at least one of the properties is true but I seem to be lost as to how to project only the names with the value true into an array.

>Solution :

One option is:

  1. Use $objectToArray to create an array from the keys and values
  2. $filter it to keep only true values
  3. Use $map to format the items
db.collection.aggregate([
  {$project: {houseDetails: {$objectToArray: "$houseDetails"}}},
  {$project: {
      houseDetails: {
        $filter: {
          input: "$houseDetails",
          cond: {$eq: ["$$this.v.flag", true]}
        }
      }
    }
  },
  {$project: {
      houseDetails: {
        $map: {
          input: "$houseDetails",
          in: "$$this.k"
        }
      }
    }
  }
])

See how it works on the playground example

You can also use $reduce to do it in two steps only:

db.collection.aggregate([
  {$project: {houseDetails: {$objectToArray: "$houseDetails"}}},
  {$project: {
      houseDetails: {
        $reduce: {
          input: "$houseDetails",
          initialValue: [],
          in: {
            $setUnion: [
              "$$value",
              {$cond: [{$eq: ["$$this.v.flag", true]}, ["$$this.k"], []]}
            ]
          }
        }
      }
    }
  }

See how it works on the playground example – reduce

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading