Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced custom schema type for custom objects or value-objects #4356

Closed
dariomncs opened this issue Jul 21, 2016 · 7 comments
Closed

Advanced custom schema type for custom objects or value-objects #4356

dariomncs opened this issue Jul 21, 2016 · 7 comments
Milestone

Comments

@dariomncs
Copy link

dariomncs commented Jul 21, 2016

I couldn't find any example of an advanced custom schema type involving custom objects (or value-objects) in Mongoose >=4.4.

I already posted a question on StackOverflow without success: http://stackoverflow.com/questions/38094817/mongoose-advanced-custom-schema-object-type.

Resuming, how can I achieve that:

  1. Every time a new model is "hydrated" from db (mongoose init), the field will be an instance of my custom object and not a plain object. For this I understand it will use the SchemaType.prototype.cast function.
  2. Every time I will save my Model the custom type field should be
    encoded and stored in a custom way (as plain object, array, string or any BSON type).
  3. If I use model.toObject() it will recursively call the model.myfield.toObject() to have a full plain object representation of the document.
@vkarpov15
Copy link
Collaborator

  1. Yep, cast()
  2. Give your Polygon class a toBSON() function https://mongodb.github.io/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#tobson-method
  3. It should already do this, no?

@vkarpov15 vkarpov15 added this to the 4.9 milestone Jul 24, 2016
@vkarpov15 vkarpov15 added the docs This issue is due to a mistake or omission in the mongoosejs.com documentation label Jul 24, 2016
@dariomncs
Copy link
Author

Thank you for the reply!

Give your Polygon class a toBSON() function https://mongodb.github.io/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#tobson-method

Yes, it work. But the debug logs of Mongoose seem to don't call it and shows it wrong (object instead of array):

Mongoose: shapes.update({ _id: ObjectId("...") }) { '$set': { bounds: { ... } } }
Trace: CALLING toBSON: [ /* array data */ ]
    at Polygon.toBSON (/var/www/test/polygons.js:136:47)
    at serializeInto (/var/www/node_modules/mongoose/test/node_modules/bson/lib/bson/parser/serializer.js:664:23)
    at serializeObject (/var/www/test/node_modules/bson/lib/bson/parser/serializer.js:280:18)
    at serializeInto (/var/www/test/node_modules/bson/lib/bson/parser/serializer.js:705:17)
    at serialize (/var/www/test/node_modules/bson/lib/bson/bson.js:47:27)
    ...
    at Collection.update (/var/www/test/node_modules/mongoose/node_modules/mongodb/lib/collection.js:1041:44)
    at NativeCollection.(anonymous function) [as update] (/var/www/test/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:125:28)
    at model.Model.$__handleSave (/var/www/test/node_modules/mongoose/lib/model.js:161:23)
    at model.Model.$__save (/var/www/test/node_modules/mongoose/lib/model.js:185:9)
    at model.Model.save (/var/www/test/node_modules/mongoose/lib/model.js:283:15)
    at model._done (/var/www/test/node_modules/hooks-fixed/hooks.js:101:24)
    at _next (/var/www/test/node_modules/hooks-fixed/hooks.js:64:28)
    at fnWrapper (/var/www/test/node_modules/hooks-fixed/hooks.js:186:18)
    at model.Object.defineProperty.value.fn (/var/www/test/node_modules/mongoose/lib/schema.js:220:11)
    at _next (/var/www/test/node_modules/hooks-fixed/hooks.js:62:30)
    at fnWrapper (/var/www/test/node_modules/hooks-fixed/hooks.js:186:18)
    at /var/www/test/node_modules/mongoose/lib/schema.js:201:17
    at /var/www/test/node_modules/mongoose/node_modules/kareem/index.js:127:16
    at process._tickDomainCallback (node.js:381:11)

It should already do this, no?

No, I tried to call the toObject() on the main model and it don't call it on the custom type.

@vkarpov15 vkarpov15 modified the milestones: 4.6, 4.9, 4.7, 4.5.10 Jul 30, 2016
@vkarpov15 vkarpov15 removed the docs This issue is due to a mistake or omission in the mongoosejs.com documentation label Jul 30, 2016
@vkarpov15
Copy link
Collaborator

Ok will make sure that debug logs handle .toBSON() and .toObject() will work for the custom type, thanks for pointing this out

@dariomncs
Copy link
Author

Thank you!

@vkarpov15 vkarpov15 modified the milestones: 4.6.1, 4.5.10 Aug 22, 2016
@vkarpov15 vkarpov15 modified the milestones: 4.6.4, 4.6.1 Sep 3, 2016
@vkarpov15 vkarpov15 modified the milestones: 4.6.7, 4.6.5 Oct 23, 2016
@vkarpov15
Copy link
Collaborator

I added the toBSON() check in 1a93d1f. Here's a better example of how to do the polygon type you're looking at:

'use strict';

var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/gh4356');
mongoose.set('debug', true);

class Polygon {
  constructor(v) {
    this.v = v;
  }

  toBSON() {
    return this.v;
  }
}

class PolygonSchema extends mongoose.SchemaType {
  cast(v) {
    return new Polygon(v);
  }
}

mongoose.Schema.Types.Polygon = PolygonSchema;

const schema = new Schema({ test: Polygon });
const M = mongoose.model('Test', schema);

M.create({ test: 5 }).then(doc => {
  console.log('done', doc);
  console.log(doc.test.toBSON());
  process.exit(0);
});

Output:

$ node gh-4356.js 
(node:14709) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
Mongoose: tests.insert({ test: 5, _id: ObjectId("581e684cc4d5933975526934"), __v: 0 })
done { __v: 0, test: Polygon { v: 5 }, _id: 581e684cc4d5933975526934 }
5

@NikhilAshodariya
Copy link

NikhilAshodariya commented Feb 24, 2018

I couldn't find any example for storing a composite object in MongoDB using Mongoose and retrieving the inner object with all the methods without typecasting.

I already posted a question on StackOverflow:
https://stackoverflow.com/questions/48960604/how-to-store-composite-object-in-mongodb-using-mongoose

Please help.

@vkarpov15
Copy link
Collaborator

@NikhilAshodariya I opened up a separate issue for this #6174.

@Automattic Automattic locked as resolved and limited conversation to collaborators Feb 26, 2018
vkarpov15 referenced this issue in mongodb-js/mongodb-core Jul 13, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants