Home > Software design >  Mongodb get specific properties in the aggregate result from a document
Mongodb get specific properties in the aggregate result from a document

Time:09-06

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

{
  _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.

CodePudding user response:

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

  • Related