简体   繁体   中英

Mongoose apply getters before find

I have inherited a Mongo collection that stores Dates as strings eg "2020-11-18" rather than as BSON Dates. I have a getter that converts this string to a js Date but I would like to query the collection by date range as follows:

const Things = mongoose.Model('Thing',
    {
        date: { type: String, get v => new Date(v) }
    }, 
    {
        toJSON: { getters: true },
        toObject: { getters: true },
    }
)

Things.find({ date: { $gt: new Date("2020-11-17"), $lt: new Date("2020-11-19") } })

It seems that the getter is not applied to documents before the find query is executed. Is there any way to do this?

As mentioned in this docs :

Getters allow you to transform the representation of the data as it travels from the raw mongodb document to the value that you see.

So your date getter will run just after the execution of the find() method. Otherwise, how the date's representation will be changed before finding the date itself !

In another words:

Things.find({ date: { $gt: new Date("2020-11-17"), $lt: new Date("2020-11-19") } })
    // getter will run here
    .then((queryResults) =>{
      
    })

Dates in that format have the fortunate property that their lexicographic sort order is the same as their chronological order.

That means that you can query them as strings and match the documents you would expect.

For example, in a collection containing

[
    {"date": "2020-11-16"},
    {"date": "2020-11-17"},
    {"date": "2020-11-18"},
    {"date": "2020-11-19"}
]

The query

db.Things.find({"date": {$gte: "2020-11-17", $lt: "2020-11-19"}})

Returns {"date": "2020-11-17"} and {"date": "2020-11-18"} , as expected.

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM