arraysmongodbmongodb-querynosqlmongo-collection

How to find documents and use aggregate to find a property in mongodb?


I have thousands of documents in a collection. below is a sample document

{
  _id: 12345,
  createdDate: "2020-07-10",
  cars: [
    {
      type: "Sedan",
      engine: [
        {
          type: "Petrol",
          power: 150,
          brake: {
            type: "Disc",
            hasABS: false
          }
        },
        {
          type: "Petrol",
          power: 190,
          brake: {
            type: "Drum",
            hasABS: false
          }
        },
        {
          type: "Diesel",
          power: 160,
          brake: {
            type: "Disc",
            hasABS: true
          }
        }
      ]
    },
    {
      type: "SUV",
      engine: [
        {
          type: "Petrol",
          power: 150,
          brake: {
            type: "Disc",
            hasABS: false
          }
        },
        {
          type: "Petrol",
          power: 190,
          brake: {
            type: "Drum",
            hasABS: false
          }
        },
        {
          type: "Diesel",
          power: 160,
          brake: {
            type: "Disc",
            hasABS: true
          }
        }
      ]
    }
  ]
}

Now I want to find cars that is created in the month of july and aggregate to find car that has brakes with abs

Below was my query:

db.getCollection('collection')
    .find({
        $and: [
            {"createdDate": {"$gte": new Date("2020-07-01"), "$lt": new Date("2020-07-10")}},
            aggregate(
                {"$unwind": "$cars"},
                {"$unwind": "$cars.engine"},
                {"$match": {"cars.engine.brake.hasABS": true}},
                {"$project": {"cars": 1}},
                {"$group": {"_id": "$cars"}}
            )
        ]
    })
    .pretty()

When I try to run the above query, I get an error. Is this how this should be done or is there any better way?


Solution

  • You cannot use .find() and .aggreate() at the same time. In this case you can use the same filter within $match aggregation stage:

    db.collection.aggregate([
        { $match: { createdDate: { $gte: "2020-07-01", $lt: "2020-07-10" } } }, // or { "$gte" : new Date("2020-07-01"), "$lte" : new Date("2020-07-10") }
        { "$unwind": "$cars" },
        { "$unwind": "$cars.engine"},
        { "$match": {"cars.engine.brake.hasABS" : true}}
    ])
    

    Mongo Playground