skip to Main Content

I am simply trying to count some documents. When using other parameters such as "type": "someType", I get the correct count. But when I use {"createdAt": {"$gte": "", "$lte": ""}} (with actual dates which are JS date objects) I get 0 as the count. Been at this for days now, and I can’t seems to find the solution…

I tried narrowing the case down to the smallest reproducable possible. Like so:

  const query = {
    createdAt: {"$gte": new Date("2023-11-01"), "$lte": new Date("2023-11-30")},
  }

const result = await Entity.countDocuments(query)

This returns 0, even though I know for 100% that I have documents matching the critera, with e.g. "createdAt": ‘2023-11-06T08:09:07.000Z’.

Trying the same countDocuments() function with other parameters returns correct number, for instance:

  const query = {
    tags: {"$nin":["false-positive", "out-of-scope"]},
  }

const result = await Entity.countDocuments(query)

The above will return the correct number of documents which does not have these two strings in its "tags"-field.

I have also tried using the "$and" operator, like so:

  const testQuery = {
    $and: [{ createdAt: { $gte: new Date("2023-10-01") } }, { createdAt: { $lte: new Date("2023-11-31") } }],
  }

But with no luck.

I have also tried logging out the query with the operators, and pasting it into MongoExpress "Advanced"-tab. This returns the correct documents, so the issue seems to be with Mongoose or Node.js.

I have no idea why it is not working with the "$gte" and "$lte", please help.

EDIT: I found one work-around, but it should not have to be necessary. In order to make it work, I had to perform the exact same query against the collection itself, rather than using the DB-model "Entity":

const colletion = mongooseConnection.collection("colecctionName")

const result = await colletion.countDocuments({ createdAt: { $gte: "2023-10-01", $lte: "2023-11-31" } })

This gives me the correct count, but I don’t see why it shouldn’t work with the DB-model itself.

2

Answers


  1. I am going to go out on a limb and post this answer because as far as I’m aware you don’t need new Date constructor and it may be that the field is not createdAt but created_at or an alternative name. Check your database to make sure you are using the correct field name. This query will return all docs with a created_at between those dates (inclusive).

    const result = await Entity.countDocuments({
       created_at: {
          $gte: "2023-10-01", 
          $lte: "2023-11-31"
       }
    });
    
    Login or Signup to reply.
  2. You can use this method, this how I do handle it

    import * as dateFns from 'date-fns';
    
    class Helper {
    
      public static generateDateRange(obj, dbType = 'NoSQL') {
        try {
          const dateRange: any = JSON.parse(obj);
          if (dateRange && dateRange.startDate && dateRange.endDate) {
            const startDate = dateFns.startOfDay(dateFns.parseISO(dateRange.startDate));
            const endDate = dateFns.endOfDay(dateFns.parseISO(dateRange.endDate));
            return dbType === 'NoSQL' ? { $lte: startDate, $gte: endDate } : Between(startDate, endDate);
          }
          return Helper.generateSingleDateRange(dateRange.startDate || dateRange.endDate || new Date(), dbType);
        } catch (e) {
          throw Helper.generateSingleDateRange(obj, dbType);
        }
      }
      
      public static generateSingleDateRange(date, dbType = 'NoSQL') {
        const startDate = dateFns.startOfDay(dateFns.parseISO(date));
        const endDate = dateFns.endOfDay(dateFns.parseISO(date));
        return dbType === 'NoSQL' ? { $lte: startDate, $gte: endDate } : Between(startDate, endDate);
      }
    }
    
    
    const startDate = new Date('2023-01-01'); // Replace with your start date
    const endDate = new Date('2023-12-31'); // Replace with your end date
    const query = { createdAt: Helper.generateDateRange({ startDate, endDate })}
    
    const result = await Entity.countDocuments(query)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search