jcspencer / mongo-relation Goto Github PK
View Code? Open in Web Editor NEWModel relationships plugin for Mongoose
Model relationships plugin for Mongoose
James,
I'd like to discuss the implementation of hasMany
. Is there a way to implement the hasMany
association without creating an array of ids on the document that owns the hasMany
relationship?
Imagine a situation where UserSchema.hasMany('Alert')
and AlertSchema.belongsTo('User')
. When a user
has 5 alerts
the association stands up. The user model will hold 5 alerts ids in an array on the user model. Great.
However, when that same users has 20000 alerts, the user model will end up with an array of 20000 ids. That doesn't seem maintainable.
Also, let's say I have an endpoint to retrieve a user's alerts created_at
after someDate
. When I query my alerts, I'll be searching with 20000 ids even though I might only find 1 document.
Is there a way to implement the hasMany
relationship by only adding the user._id
to the alert
model?
Is ready to use hasOne?
Maybe I'm missing something, however what happens if a Schema has two fields of the same model? For example, taking the example from the main site, let's say we also want to keep track of an editor.
var mongoose = require('mongoose');
require('mongo-relation');
// UserSchema stores an Array of ObjectIds for posts
var UserSchema = new mongoose.Schema({
posts: [mongoose.Schema.ObjectId],
edited: [mongoose.Schema.ObjectId]
});
// PostSchema stores an ObjectId for the author
var PostSchema = new mongoose.Schema({
title : String
, author : mongoose.Schema.ObjectId
, editor : mongoose.Schema.ObjectId
});
// Attach the plugin
UserSchema.hasMany('Post', {through: 'posts'});
UserSchema.hasMany('Post', {through: 'edited'});
PostSchema.belongsTo('User', {through: 'author'});
PostSchema.belongsTo('User', {through: 'editor'});
var User = mongoose.model('User', UserSchema)
, Post = mongoose.model('Post', PostSchema);
Am I missing something? Or can two models only be associated once?
Thanks!
I'm currently looking at things that would be a good addition for a 1.0 release.
The list I have so far:
.create()
on singular fields created view .hasMany()
, using the Mongoose's Virtuals..hasMany()
would be helpful, especially when storing large amounts of child documents.If you have questions/suggestions, let me know, I'm sure there are many other things that would make 1.0 even better 😄
In reference to #10, one of the aims for v1.0.0 is to move from patching MongooseArray
and Schema
and to instead use Mongoose's Virtuals. This would allow mongo-relation to be used as Mongoose Plugin, instead of monkey-patching via a require call.
This would involve moving the following methods into Virtuals on Schemas:
As well as adding .create()
methods to each relationship field, wether it be an array or single document.
The update is in the master branch, but the version published in npm still has 'run' on line 320
With populate()
, I can use whatever I want as keys, and it will grab the children or understand when I use Numbers to map the relations:
// UserSchema stores an Array of ObjectIds for posts
var UserSchema = new mongoose.Schema({
_id: Number,
posts: [Number]
});
// PostSchema stores an ObjectId for the author
var PostSchema = new mongoose.Schema({
_id: Number,
title : String,
author : Number
});
If I run this:
// Attach the plugin
UserSchema.hasMany('Post');
PostSchema.belongsTo('User', {through: 'author'});
var User = mongoose.model('User', UserSchema),
Post = mongoose.model('Post', PostSchema);
var user = new User();
var post = new Post();
user.posts.append(post, function(err, post){
// post.author === user._id
// user.posts.id(post._id) === post._id
});
user.save();
I get this:
node_modules/mongoose/lib/schema/number.js:201
throw new CastError('number', value, this.path);
^
CastError: Cast to number failed for value "undefined" at path "posts"
at SchemaNumber.cast (node_modules/mongoose/lib/schema/number.js:201:9)
at Array.MongooseArray._cast (node_modules/mongoose/lib/types/array.js:114:30)
at Object.map (native)
at Array.MongooseArray.push (node_modules/mongoose/lib/types/array.js:268:23)
at Array.MongooseArray.append (node_modules/mongo-relation/lib/relationships.js:368:28)
at Object.<anonymous> (doc/fromdocs.js:30:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
I'm trying to use mongo-relation with models that are in separate files.
in foo.js:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
Bar = require('./bar');
require('mongo-relation');
var FooSchema = new Schema({
bar: Schema.Types.ObjectId
});
FooSchema.hasOne('Bar', { through: 'bar' });
module.exports = mongoose.model('Foo', FooSchema);
and bar.js:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
require('mongo-relation');
var BarSchema = new Schema({
stuff: String
});
// no belongsTo, as a Bar can be in a Foo, but also in a Baz and a Quux
module.exports = mongoose.model('Bar', BarSchema);
In some other file, I var Foo = require('foo.js');
and then try:
var foo = new Foo();
foo.bar.stuff = 'Lorem ipsum';
Then I get the error message "Cannot set property 'stuff' of undefined". Clearly, I'm supposed to require Bar in some way, but I don't really understand where. Your examples have all the models in the same file, but that's not an option for this project, as we have way too many models.
Thanks for any help, and kind regards,
André Fischer
P.S. Yes, I'm a bit new to Node and Mongoose...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.