nabeel
nabeel

Reputation: 961

Multi-dimensional array in Mongoose schema

How can I define a multi-dimensional array in a Mongoose schema? I want to have a 2d array in my mongoose schema in order to locate a room in a hotel something like this.

var Room = new Schema({
   number: Number,
   type: String, // Room type id    
});

var Hotel = new Schema({
   ...
   rooms: [[Room]]    
});

Here's the error I get...

D:\projects\HotelBox\node_modules\mongoose\lib\schema\array.js:58
this.caster = new caster(null, castOptions);
              ^
TypeError: object is not a function
at new SchemaArray

I can fix it by defining rooms as Schema.Types.Mixed but then I can't validate room data at the time of creation.

Upvotes: 2

Views: 8113

Answers (3)

Alex Po
Alex Po

Reputation: 2055

You can place coordinates of rooms in your model e.g.

var Room = new Schema({
    x: Number,
    y: Number,
    room_number: Number,
    room_type: String, // Room type id    
});

var Hotel = new Schema({
   ...
   rooms: [Room]    
});

Then create an array of all rooms:

var rooms = [];
var i = 0;
for (var y = 0; y<dim; y++) {
  for (var x = 0; x < dim; x++) {
    rooms[i] = new Room(x, y, ...);
  }
}

Then insertMany in mongoose. And on client side you can iterate over all array by chunking it e.g.

var chunks = _.chunk(_.range(side*side), side)
for (var chunk in chunks) {
  for (var i in chunk) {
    console.log(rooms[i]);
  }
}

Upvotes: 0

Diosney
Diosney

Reputation: 10590

AFAIK, currently there is no such support in mongoose for multidimensional arrays utilisation.

That being said, and as you have been pointed, you can workaround this by using the Schema.Types.Mixed SchemaType, but then you will lose all the goodies that came to use native mongoose types.

However, you can overcome this by definining your own validations by using custom validators, as pointed at the official docs (they are very easy to use). The only caveat with custom validations is that they are triggered only when saving an instance.

If what you need is to trigger the validations and initilization time, you can use the more low-level middleware hooks which gives you fine grained control since you can invoke them at the following actions:

  • init
  • validate
  • save
  • remove

(note the init hook)

Hope this helps you to overcome your use case.

Upvotes: 3

H&#252;seyin BABAL
H&#252;seyin BABAL

Reputation: 15550

Your schema definition must be (I also refactored your field names according to your schema. It can be dangerous to use reserved keyword like fields);

var Room = new Schema({
    room_number: Number
    room_type: String, // Room type id    
});

var Hotel = new Schema({
   ...
   rooms: [Room]    
});

Upvotes: -1

Related Questions