• Stars
    star
    121
  • Rank 293,924 (Top 6 %)
  • Language
    JavaScript
  • Created almost 11 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Mongoose plugin to create maintain one-many and many-many bidirectional relationships between two entities

mongoose-relationship

Note: Maintenence on this module is deprecated. I had personally been using it for a project and over time have realized that bi-directional relationships in mongoose can become extremely complex and hinder performance as a project grows. The more I learn about mongo and designing data for it, the less likely these relationships make sense.

A mongoose plugin that creates and manages relationships between two separate models. These relationships can be One-To-One, One-To-Many, or Many-To-Many. These changes are currently one-direction. If you manipulate a parents "child" property or collection, the child values will not be updated. Only changes made to the child model will update its parent.

Install

Install via NPM

    npm install mongoose-relationship

Usage

One-To-Many

var mongoose = require("mongoose"),
    Schema = mongoose.Schema,
    relationship = require("mongoose-relationship");

var ParentSchema = new Schema({
    children:[{ type:Schema.ObjectId, ref:"Child" }]
});
var Parent = mongoose.model("Parent", ParentSchema);

var ChildSchema = new Schema({
    parent: { type:Schema.ObjectId, ref:"Parent", childPath:"children" }
});
ChildSchema.plugin(relationship, { relationshipPathName:'parent' });
var Child = mongoose.model("Child", ChildSchema)

var parent = new Parent({});
parent.save();
var child = new Child({parent:parent._id});
child.save() //the parent children property will now contain child's id
child.remove() //the parent children property will no longer contain the child's id

Many-To-Many

var mongoose = require("mongoose"),
    Schema = mongoose.Schema,
    relationship = require("mongoose-relationship");

var ParentSchema = new Schema({
    children:[{ type:Schema.ObjectId, ref:"Child" }]
});
var Parent = mongoose.model("Parent", ParentSchema);

var ChildSchema = new Schema({
    parents: [{ type:Schema.ObjectId, ref:"Parent", childPath:"children" }]
});
ChildSchema.plugin(relationship, { relationshipPathName:'parents' });
var Child = mongoose.model("Child", ChildSchema)

var parent = new Parent({});
parent.save();
var parentTwo = new Parent({});
parentTwo.save();

var child = new Child({});
child.parents.push(parent);
child.parents.push(parentTwo);
child.save() //both parent and parentTwo children property will now contain the child's id
child.remove() //both parent and parentTwo children property will no longer contain the child's id

Many-To-Many with Multiple paths

var mongoose = require("mongoose"),
    Schema = mongoose.Schema,
    relationship = require("mongoose-relationship");

var ParentSchema = new Schema({
    children:[{ type:Schema.ObjectId, ref:"Child" }]
});
var Parent = mongoose.model("Parent", ParentSchema);

var OtherParentSchema = new Schema({
    children:[{ type:Schema.ObjectId, ref:"Child" }]
});
var OtherParent = mongoose.model("OtherParent", OtherParentSchema);

var ChildSchema = new Schema({
    parents: [{ type:Schema.ObjectId, ref:"Parent", childPath:"children" }]
    otherParents: [{ type:Schema.ObjectId, ref:"OtherParent", childPath:"children" }]
});
ChildSchema.plugin(relationship, { relationshipPathName:['parents', 'otherParents'] });
var Child = mongoose.model("Child", ChildSchema)

var parent = new Parent({});
parent.save();
var otherParent = new OtherParent({});
otherParent.save();

var child = new Child({});
child.parents.push(parent);
child.otherParents.push(otherParent);
child.save() //both parent and otherParent children property will now contain the child's id
child.remove() //both parent and otherParent children property will no longer contain the child's id

One-To-One

This usage scenario will overwrite the parent's field of multiple children are assigned the same parent. The use case for this operation seems to be limited and only included for a sense of completion.

var mongoose = require("mongoose"),
    Schema = mongoose.Schema,
    relationship = require("mongoose-relationship");

var ParentSchema = new Schema({
    child:{ type:Schema.ObjectId, ref:"Child" }
});
var Parent = mongoose.model("Parent", ParentSchema);

var ChildSchema = new Schema({
    parent: { type:Schema.ObjectId, ref:"Parent", childPath:"child" }
});
ChildSchema.plugin(relationship, { relationshipPathName:'parent' });
var Child = mongoose.model("Child", ChildSchema)

var parent = new Parent({});
parent.save();
var child = new Child({parent:parent._id});
child.save() // The parent's child property will now be set to the child's _id;
child.remove() // The parent's child property will now be unset

Options

Plugin

The plugin currently has the following options

  • relationshipPathName

    A string or array to let the plugin know which path(s) on your schema the relationship will be created. Defaults to relationship

  • triggerMiddleware

    Boolean value which, if set to true, will explicitly save any parents entities when a relationship is updated causing save middleware to execute. Defaults to false

Path Value

When creating a path on a schema that will represent the relationship, the childPath option is required

  • childPath

    A string which should match an existing path in target ref schema. If this path does not exist the plugin will have no affect on the target ref.

  • validateExistence

    Boolean value that tells mongoose-relationship to ensure that the parent exists before setting the relationship for the child. Defaults to false

  • upsert

    Boolean value that controls whether a parent should be created if it does not exist upon child save. Defaults to false

Tests

Test can be run simply by installing and running mocha

npm install -g mocha
mocha

Authors

Mike Sabatini @mikesabatini

License

Copyright Mike Sabatini 2014 Licensed under the MIT License. Enjoy