Reputation: 961
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
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
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 validation
s 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
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