1

I am new to Sails.js and OrientDB. I am trying to figure out how to create a model that has multiple edges using the sails-orientDB adapter.

I have a vehicle model that stores basic vehicle information and a vehicle color:

module.exports = {
  schema: true,
  tableName: 'Vehicle',
  attributes: {
    id: {
      type: 'string',
      primaryKey: true,
      columnName: '@rid'
    },
    make: {
      type: 'string',
      unique: false,
      required: true
    },
    model: {
      type: 'string',
      unique: false,
      required: true
    },
    year: {
      type: 'int',
      int: true,
      unique: false,
      required: true
    },
    color: {
      collection: 'Vehicle_Color',
      via: 'color',
      edge: 'vehicleColor'
    }  
  }
};

And a vehicle Color Model:

module.exports = {
  schema: true,
  tableName: 'Vehicle_Color',
  attributes: {
    id: {
      type: 'string',
      primaryKey: true,
      columnName: '@rid'
    },
    name: {
      type: 'string',
      unique: true,
      required: true
    },
    hexCode: {
      type: 'string',
      hexColor: true
    }
  }
};

I want each Vehicle to be able to have multiple colors. For Example

  • VehicleA -> Red
  • VehicleA -> Blue
  • VehicleA -> Yellow

The documentation shows how to set up a one to one relation, but I cant figure out the correct way to do one to many, or many to many. I looked into using this adapter: npmjs.com/package/waterline-orientdb but that looks like it negates the benefits (github.com/appscot/waterline-orientdb/issues/29) of using a graph Database.

Would I simply create an edge model like:

module.exports = {
  schema: true,
  tableName: 'Vehicle_Color',
  attributes: {
    vehicleID: {
      type: 'string',      
    },
     colorID: {
      type: 'string',      
    },
  }
};

And then in my model store an array of those edges? Is there a better way to do this? Thanks in advance.

Gantrim
  • 37
  • 6

1 Answers1

1

Waterline-orientdb was just updated (v0.10.40) and now it supports edges in Many-to-many associations (in addition to many-to-many through). Many-to-many associations are simpler to handle so I recommend those. The model specification is the same as that described on waterline-docs.

Back to your specific case.

Vehicle model

You should drop the edge keyword as it may cause exceptions like the one below when dealing with nested associations:

     Error: Unknown rule: edge
  at Object.matchRule (/Users/warchild/Development/node/waterline-orientdb/node_modules/waterline/node_modules/anchor/lib/match/matchRule.js:37:11)

You can use the below outside attributes to rename the edge (otherwise waterline will name it to something like vehicleColor_color__Vehicle_Color_cars):

  joinTableNames: {
    color: 'has_color'  // I've used a different name to distinguish from Color Model
  },

and replace your color attribute with:

color: {
  collection: 'Vehicle_Color',
  via: 'cars',
  dominant: true
}

Vehicle_Color

Add the following attribute so vehicle_color knows about vehicle:

cars: {
  collection: 'Vehicle',
  via: 'color'
}

Given you will be using many-to-many associations you don't need to create a model for the edge, waterline will create it for you.

That should do it, let me know otherwise.

UPDATE: waterline-orientdb has been renamed sails-orientdb.

Dário
  • 2,002
  • 1
  • 18
  • 28