I have the following model settings:
const mongoose = require('mongoose');
const itemSchema = new mongoose.Schema({
areas: [{
area: {
type: Number,
required: true,
enum: [0, 1, 2, 3, 4, 5],
}
}],
}, {
timestamps: true
});
const Item = mongoose.model('Item', itemSchema);
module.exports = Item;
When I try to save an instance in the DB:
const item = new Item({
areas: [1, 2, 3],
});
item.save();
I get the following error:
Item validation failed: areas: Cast to embedded failed for value "1" at path "areas"
CastError: Cast to embedded failed for value "1" at path "areas"
Why do I get this error? I can't find what Schema rule I broke..
I think its because you are setting the areas as an array of objects that contains area property, like:
[{area: 1}, {area: 2}, {area: 3}]
Maybe you could try set it as:
areas: [{
type: Number,
required: true,
enum: [0, 1, 2, 3, 4, 5],
}],
Related
I want to calculate average rating for products based on comments rate,
exactly I want to return products object with one more property in response when client call get all product api
my product schema is like below, thank you in advance.
const mongoose = require("mongoose");
const { s, rs, n, rn, ref, rref } = require("../utils/mongo");
let commentSchema = new mongoose.Schema(
{
user: rref("user"),
body: rs,
rate: {
...n,
default: 0,
enum: [0, 1, 2, 3, 4, 5],
},
},
{ timestamps: true }
);
let schema = new mongoose.Schema(
{
user: rref("user"),
name: rs,
description: s,
images: [s],
price: rn,
discount: n,
sizes: [sizeSchema],
categories: [ref("category")],
tags: [s],
comments: [commentSchema],
rating: n,
inStock: {
type: Boolean,
default: true,
},
stock: n,
sold: {
...n,
default: 0,
},
view: {
...n,
default: 0,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("product", schema);
I want to return in response something like this:
let result = [
{
name: 'product name',
comments: [
{
user: "2a2sdw22das5262123223",
body: "good product",
rate: 4
},
{
user: "2a2sdw22das5262123223",
body: "good product",
rate: 2
}
],
avgRate: 2, // how to calculate this?
price: 20
...
}
]
You can use aggregation pipeline to do that, it will add the avgRating field avgRate which you can use for future ref:
db.collectionName.aggregate([{ $addFields : { avgRate: { $avg: "$comments.rate"} } }])
I am trying to save array of objects, but it is just saving the ObjectIds instead of whole objects, even thought in schema there is no refference or something like that.
So, I have this schema:
let MatchPlayerSchema = new Schema({
deck: {type: Array, default: []}
});
And I am trying to save this array tooken from database (playerDeck):
[ { _id: 5a1fc7ee667b103aace5f3ec,
magicResist: 10,
armor: 10,
attack: 10,
health: 10,
name: 'Test',
__v: 0,
type: 'CardUnit' },
{ _id: 5a1fc7ee667b103aace5f3ec,
magicResist: 10,
armor: 10,
attack: 10,
health: 10,
name: 'Test',
__v: 0,
type: 'CardUnit' }]
Like this:
let player = new MatchPlayer();
player.deck = playerDeck;
player.save();
However, the result is:
"deck" : [
ObjectId("5a1fc7ee667b103aace5f3ec"),
ObjectId("5a1fc7ee667b103aace5f3ec")
]
I have tried to set deck to: [Schema.Types.Mixed], but it didnt not help either.
When I try to save something just like: ['test', 'test'], it saves alright.
I just can not figure out, what am I doing wrong.
Any ideas? Thank you
I had the same issue and setting the
mongoose.set('debug', true);
helped me to see what mongoose actually sending to the DB.
I was having in the Schema
const ChatSchema = mongoose.Schema({
messages: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Message',
}],
isRemoved: {
type: Boolean,
default: false,
required: true
}
});
After switching the type to mongoose.Schema.Types.Mixed it worked perfectly. This is how I was invoking an update
Chat.findOneAndUpdate({ _id: req.params.chatId }, { $push: { messages: message }},{new: true});
let MatchPlayerSchema = new Schema({
deck: {
type: Schema.Types.Mixed
}
});
You should be able to store an array of objects into 'deck'
I'm trying to update an element of an array inside my model. It's a simple array of Strings. When I run the code, the element is updated, but it's inserting a new array with the value 'newType'. I'm using mongoose 4.11.7.
The result I expect is:
['a', 'b', 'newType'] but after the update it's returning ['a', 'b', ['newType']].
const profile = await Profile.findOneAndUpdate({
_id: 1,
types: 'oldType'
}, {
$set: {
'types.$': 'newType'
}
});
My Model is:
const schema = new Schema({
types: [{
type: String,
trim: true
}]
}, {
timestamps: true,
collection: 'Profile'
});
I'd like to store the following:
var TestSchema = new Schema({
name: {
type: String
},
regions: [RegionSchema]
}
var RegionSchema = new Schema({
name: {
type: String
},
minX: {
type: Number
},
minY: {
type: Number
},
minZ: {
type: Number
},
maxX: {
type: Number
},
maxY: {
type: Number
},
maxZ: {
type: Number
},
children: [this]
});
So as you can see I'm trying to make a region object, able to contain region objects, however this fails to save without exception, presumably the [this] in the schema gets stuck in some endless loop or something.
How can I make this to work for nesting regions?
The json payload I could expect to send to this schema:
name: "test123",
regions: [
{
name: "TestRegion",
minX: 0,
minY: 0,
minZ: 0,
maxX: 100,
maxY: 255,
maxZ: 100,
children: [
{
name: "TestRegionChild",
minX: 3,
minY: 3,
minZ: 3,
maxX: 97,
maxY: 252,
maxZ: 97,
children: []
}
]
}
]
I appreciate any help, thank you.
If your other regions are saved first, you can save the children as a list of objectIds like this:
children: [{
type: Schema.ObjectId,
ref: 'Region'
}]
Another option is to redesign your Schema and have a 'parent' on your Region and delete the 'children' field. Then when you need to get all the children you can query easily and not have big nested objects.
var RegionSchema = new Schema({
--- other fields omitted ---
parent: {
type: Schema.ObjectId,
ref: 'Region'
}
});
I am trying to make default values for array in mogoose schema:
warning:
type: Array
default: [10, 50, 99]
Am I right in such decision or there is some other way to do this?
Regarding to the Mongoose-Documentation, your way is correct.
Here a small example:
var arrayTestSchema = new Schema({
anArray: {
type: Array,
'default': [1, 2, 3]
}
});
And a link to the related documentation page: http://mongoosejs.com/docs/2.7.x/docs/defaults.html
for Mongoose v5.x
If you want to specify the type of the array child, you can define it like example below:
const BlogSchema = new Schema({
tags: {
type: [String],
default: ["tech", "economy"],
},
})
or
const BlogSchema = new Schema({
tags: {
type: [
{
type: String,
// Another properties
},
],
default: ["tech", "economy"],
},
})
References:
https://mongoosejs.com/docs/schematypes.html#arrays
It should be a json, I don't know what is what you posted there.
new Schema({
warning: { type: Array, default: [10, 50, 99] }
})