Ad

How Can I Find Subdocument Using Mongoose?

- 1 answer

I have defined a model like this.

const ShotcountSchema = new Schema({
  shotCountId : {
    type : ObjectId,
    required : true,
    ref : 'member-info'
  },
  userId : {
    type : String,
    required : true,
    unique : true  
  },
  shot : [{
    shotId : {
      type : String,
      required : true,
      unique : true
    },
    clubType : {
      type : String,
      required : true
    }
    createdAt : {
      type : Date,
      default : Date.now
    }
  }]
});

If you perform a query to find subdocuments based on clubType as follows, only the results of the entire document are output.

For example, if I write the following code and check the result, I get the full result.

const shotCount = await ShotcountSchema.aggregate([
  {
    $match : { shotCountId : user[0]._id }
  },
  {
    $match : { 'shot.clubType' : 'driver' }
  }
]);

console.log(shotCount[0]); // Full result output

I would like to filter the subdocuments via clubType or createdAt to explore. So, I want these results to be printed.

{
  _id: new ObjectId("61d67f0a74ec8620f34c57ed"),
  shot: [
    {
      shotId: 'undefinedMKSf*Tf#!qHxWpz1hPzUBTz%',
      clubType: 'driver',
      shotCount: 20,
      _id: new ObjectId("61d67f0a74ec8620f34c57ef"),
      createdAt: 2022-01-06T05:32:58.391Z
    }
  ]
}

How should I write the code?

Ad

Answer

db.collection.aggregate([
  {
    "$match": {
      _id: ObjectId("61d67f0a74ec8620f34c57ed"),
      "shot.clubType": "driver",
      shot: {
        $elemMatch: {
          $and: [
            {
              "createdAt": {
                $gte: ISODate("2022-01-07T05:32:58.391Z")
              }
            },
            {
              "createdAt": {
                $lte: ISODate("2022-01-09T05:32:58.391Z")
              }
            }
          ]
        }
      }
    }
  },
  {
    "$set": {
      shot: {
        "$filter": {
          "input": "$shot",
          "as": "s",
          "cond": {
            $and: [
              {
                "$eq": [
                  "$$s.clubType",
                  "driver"
                ]
              },
              {
                "$gte": [
                  "$$s.createdAt",
                  ISODate("2022-01-07T05:32:58.391Z")
                ]
              },
              {
                "$lte": [
                  "$$s.createdAt",
                  ISODate("2022-01-09T05:32:58.391Z")
                ]
              }
            ]
          }
        }
      }
    }
  }
])

mongoplayground

Ad
source: stackoverflow.com
Ad