aravindnc / mongoose-aggregate-paginate-v2

A cursor based custom aggregate pagination library for Mongoose with customizable labels.
MIT License
131 stars 23 forks source link

[SERIOUS] Setters/ Getters not working, docs fail instanceof mongoose.Document check #50

Open vresetnikov opened 1 year ago

vresetnikov commented 1 year ago

Hello,

We have been developing a system for money operations where Decimal128 field values need to be converted to string to appear correctly in JSON. After running tests trying to isolate the problem, it has become apparent that mongoose-aggregate-paginate-v2 does not seem to be able to use virtuals, namely the mongoose's native set and get functionality as the document Decimal128 fields do not get converted and instead appear in Json as such:


"totalValue": {
      "$numberDecimal": "2978.60"
  },

Notice the preceding $numberDecimal.

Additionally, running the following check: results.docs.map(result => result instanceof mongoose.Document) will fail and return false, which might be related to why the getters fail. Doesn't this library return the aggregated documents?

This is a very urgent and pressing issue for us, we would be immensely grateful if a reply/ suggestion/ solution could be provided.

Thank you very much

vresetnikov commented 1 year ago

After reading carefully the docs on Aggregate I think I have come to understand that aggregate returns a plain JS object and therefore no Document related methods can be called on it and this has nothing to do with the library. Any suggestions on how could the desired result be achieved without abandoning the aggregation?

aravindnc commented 1 year ago

@vresetnikov Based on my understanding, getters/setters are registered at the schema level, so aggregate output will not have access to model instance.

Let's see if anybody have other methods to overcome this.

oscar-v0 commented 1 year ago

Not sure if this solves your issue but this worked for me. The solution is to instantiate a new Document instance by passing in the plain JS object as parameter, e.g:

const users = await UserModel.aggregatePaginate(...);
users.docs = users.docs.map(doc => new UserModel(doc));

// This now works
await UserModel.populate(users.docs, "messages");