Home > Enterprise >  Mongoose: Filtering documents by date range returns 0 documents
Mongoose: Filtering documents by date range returns 0 documents

Time:02-20

I have this model:

const HistorySchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: "users",
  },
  category: {
    type: String,
    enum: category_enum,
    required: true,
  },
  date: {
    type: Date,
    default: Date.now,
  },
});

So a document could be:

{
    "_id": "60ddad447b0e9d3c4d4fd1f1",
    "user": "60dc8118118ea36a4f3cab7d",
    "category": "LOGIN",
    "date": "2021-03-02T00:00:00.000Z",
    "__v": 0
},

I am trying to get events that happen in a given year with this:

const getEventsOfYear = async (year) => {
  let response = {
    events_of_year_per_user: null,
  };

  const start_date_of_the_year = moment(year);
  const end_date_of_the_year = moment(year).endOf("year");
  const filter_stage = {
    $match: {
      date: {
        $gte: start_date_of_the_year,
        $lte: end_date_of_the_year,
      },
    },
  };
  const pipeline = [filter_stage];
  const history_events_with_aggregate = await History.aggregate(pipeline);
  response.events_of_year_per_user = history_events_with_aggregate;
  return response;
};

The problem is that this always returns an empty array:

{
    "events_of_year_per_user": []
}

Any idea what I'm doing wrong?


EDIT 1: I even tried with another model and direct date input instead of using moment and it's still the same result:

const filter_stage = {
  $match: {
    date: {
      $gte: "2022-01-01",
      $lte: "2022-12-30",
    },
  },
};

const pipeline = [filter_stage];
const history_events_with_aggregate = await userModel.aggregate(pipeline);

But, using find works:

  const history_events_with_aggregate = await userModel.find({
    date: { $gte: "2022-01-01", $lte: "2022-12-30" },
  }); 

CodePudding user response:

You need to indicate ISODate() in the values of your filter.

const filter_stage = {
  $match: {
    date: {
      $gte: ISODate("2022-01-01T00:00:00"),
      $lte: ISODate("2022-12-30T00:00:00")
    }
  }
};

CodePudding user response:

This is how I solved the issue:

  const filter_stage = {
    $match: {
      date: {
        $gte: new Date("2022-01-01"),
        $lte: new Date("2022-12-30"),
      },
    },
  };

And if you want to use moment:

 const start_date_of_the_year = moment(year);
 
  const end_date_of_the_year = moment(year).endOf("year");
  
  const filter_stage = {
    $match: {
      date: {
        $gte: new Date(start_date_of_the_year),
        $lte: new Date(end_date_of_the_year),
      },
    },
  };
  • Related