Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set limit for array size in Mongoose schema

Would you be kind to tell me is there any way to set limitation on array size while creating Mongoose schema. For example

 var peopleSchema = new Schema({
    name: {
        type: String,
        required: true,
        default: true
    },
   /* here I want to have limit: no more than 10 friends.
    Is it possible to define in schema?*/
    friends: [{
        type: Schema.Types.ObjectId,
        ref: 'peopleModel'
    }]
})
like image 772
Ignat Galkin Avatar asked Feb 14 '15 10:02

Ignat Galkin


4 Answers

With a small tweak to your schema setup you can add a validate option:

var peopleSchema = new Schema({
  name: {
    type: String,
    required: true,
    default: true
  },
  friends: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'peopleModel'
    }],
    validate: [arrayLimit, '{PATH} exceeds the limit of 10']
  }
});

function arrayLimit(val) {
  return val.length <= 10;
}
like image 194
Jason Cust Avatar answered Oct 19 '22 05:10

Jason Cust


starting from mongo 3.6 you can add validation for a collection at server end, each document inserted/updated will be validated against the validator $jsonSchema, only the valid gets inserted, validation error will be for invalid documents

db.createCollection("people", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: [ "name" ],
         properties: {
            name: {
               bsonType: ["string"],
               description: "must be a string"
            },
            friends: {
               bsonType: ["array"],
               items : { bsonType: ["string"] },
               minItems: 0,
               maxItems: 10,
               description: "must be a array of string and max is 10"
            }
         }
      }
   }
});

collection

> db.people.find()

valid document

> db.people.insert({name: 'abc' , friends : ['1','2','3','4','5','6','7','8','9','10']})
WriteResult({ "nInserted" : 1 })

invalid document

> db.people.insert({name: 'def' , friends : ['1','2','3','4','5','6','7','8','9','10', '11']})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})

find

> db.people.find()
{ "_id" : ObjectId("5a9779b60546616d5377ec1c"), "name" : "abc", "friends" : [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ] }
> 
like image 25
Saravana Avatar answered Oct 19 '22 04:10

Saravana


You can use $slice modifier at the time you push new friend id into your array https://docs.mongodb.com/manual/reference/operator/update/slice/#up._S_slice

$push: {
  friends: {
   $each: [id],
   $slice: -10
  }
}
like image 5
Luis Avatar answered Oct 19 '22 04:10

Luis


This is my schema and array limit on assignedToId via an external function.

const mongoose = require("mongoose");
    const Schema = mongoose.Schema;

const taskSchema = new Schema({
  parentTask: {
    trim: true,
    type: Schema.Types.ObjectId,
    ref: "task",
  },
  assignedToId: [{
    trim: true,
    type: Schema.Types.ObjectId,
    ref: "Employees",
  }],
  createdBy: {
    trim: true,
    type: Schema.Types.ObjectId,
    ref: "Employees",
    required: [true, "User ID is required"]
  },
  createdByName: {
    trim: true,
    type: String,
    required: [true, "Creater name is required"]
  },
},
  {
    timestamps: true
  });

// Validations for assignedTo employees' size
taskSchema.path('assignedToId').validate(function (value) {
  console.log(value.length)
  if (value.length > 10) {
    throw new Error("Assigned person's size can't be greater than 10!");
  }
});

const Tasks = mongoose.model("Tasks", taskSchema);

module.exports = Tasks;
like image 1
Ankit Kumar Rajpoot Avatar answered Oct 19 '22 05:10

Ankit Kumar Rajpoot