Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose, express- create schema with array of objects

I try to create mongoose schema containing array of objects. Schema looks like:

const mapSchema = new Schema({
  name: {
    type: String
  },
  description: {
    type: String
  },
  rate: {
    type: Number,
    default: 0
  },
  sumOfRates: {
    type: Number,
    default: 0
  },
  places: [
    {
      name: String,
      description: String,
      difficulty: { type: String, default: 0 },
      sumOfRates: { type: String, default: 0 },
      lat: Number,
      lng: Number
    }
  ]
}, {
  timestamps: true
})

Places is array of objects. I tried to create mongoose schema and use it as element of places array(places: [ref: 'placeSchema']).

const placeSchema = new Schema({
  name: {
    type: String
  },
  description: {
    type: String
  },
  difficulty: {
    type: Number,
    default: 0
  },
  lat: {
    type: Number
  },
  lng: {
    type: Number
  }
})

But I think it would create another, separeted document in mongo(places document). Does it? I try to avoid such situation To keep it in one document.Now(code pasted above), gives me an error, when i try to insert json in postman:

{
    "name": "ergergergg",
    "description": "rgergrg",
    "places": [
        {
            "name":"cvcv",
            "description":"rgergrg",
            "lat":233,
            "lng":232
        }]
}

Error:

ValidationError: places: Cast to Array failed for value "[object Object]" at path "places"

Why such error? How to fix this?

like image 569
Krystian Fras Avatar asked Sep 19 '17 13:09

Krystian Fras


2 Answers

The appropriate way to go would be to use of a sub schema.

const subSchema = new Schema({
  name: {
    type: String,
  },
  description: {
    type: String,
  },
  difficulty: {
    type: Number,
    default: 0,
  },
  lat: {
    type: Number,
  },
  lng: {
    type: Number,
  },
});

const mapSchema = new Schema({
  name: {
    type: String,
  },
  description: {
    type: String,
  },
  rate: {
    type: Number,
    default: 0,
  },
  sumOfRates: {
    type: Number,
    default: 0,
  },
  places: [subSchema],
}, {
  timestamps: true
});

To insert a new data

mapSchema.insert({
   name: "ergergergg",
   description: "rgergrg",
   places: [
        {
            name: "cvcv",
            description: "rgergrg",
            lat: 233,
            lng: 232,
        },
        {
            name: "22",
            description: "erwer2",
            lat: 123,
            lng: 321,
        },
   ],
});
like image 131
Orelsanpls Avatar answered Oct 14 '22 23:10

Orelsanpls


To make the subSchema optional, you can maybe do something like this @DanMossa :

    pages: {
        type: [subSchema],
        required: false
    },
like image 30
Th3Ph4nt0m Avatar answered Oct 14 '22 22:10

Th3Ph4nt0m