Lab: Apply the Subset Pattern

Is there a way to check the constraint about the fixed cardinality ( 5 ) of arrays in the schema directly? The constraint must be respected by application code updating the corresponding array each time we have a new rewiew or new question? Thanks in advance

I don’t think there’s a way of enforcing/capping the size of an array. I know of capped collections but I’ve not heard of capped arrays. The only two things I can think of are:

  • You could create a max_array_size integer field which will dictate the max size of the the array that’s allowed, then on inserting a new item, compare the $size of the array to the max_array_size field before proceeding.
    Or
  • Handle this at the application layer by setting a constant value of the max size of the array, then on inserting a new item, compare this const value against the $size of the array before proceeding.
1 Like

The MongoDB Query Language has an operator called $slice.
Using it with an update operator like $push to add to your array will give you the desired behavior:

db.foo.insert({_id: 1})
for (i=1; i<=15; i++) {
    db.foo.update({_id: 1}, { "$push": { "top10": { "$each": [i], $slice: -10 }}})
}
db.foo.find({_id: 1})
{ "_id" : 1, "top10" : [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ] }

Regards,
Daniel.

1 Like

You taught me something new there @danielcoupal :slightly_smiling_face::+1:

In addition to what @danielcoupal suggested, this got me thinking about JSON Schema Validation and as it turns out, from version 3.2 you can implement this sort of validation at schema level.

Implement this using the validator option:
db.createCollection( "nameOfCollection", { validator: { $jsonSchema: { bsonType: "array", maxItems: 5 } }, validationAction: "warn" })

image

Get validator info using getCollectionInfos()
db.getCollectionInfos({ name: "nameOfCollection", type: "collection" })

Sources:

3 Likes

Hi Daniel,
i have a doubt about using $jsonSchema command,
If i have an array as field of the collection there is a way to indicate the bsonType of the elements?
How can i model an array of integers as example?
What can i add in the following example to answer my question?
Thanks in advice.
Gianfranco

db.createCollection(“foo1”, {
validator: {
$jsonSchema: {
bsonType: “object”,
required: [ “major”, “score” ],
properties: {
“major”: {
enum: [ “Math”, “English”, 3, null ],
description: “can only be one of the enum values and is required”
},
“score”: {
bsonType: “array”,
minItems: 0,
maxItems: 3,
uniqueItems: true,
description: “must be an array and is required”
}
}
}
},
“validationLevel”: “strict”,
“validationAction”: “error”
})

Gianfranco,

There is an “items” attribute to describe the elements of an array in the JSONSchema spec.
For example, if you want to restrict the score elements to be integers, the validator would look like the following:

validator_example = {
    $jsonSchema: {
        bsonType: "object",
        required: [ "score" ],
        properties: {
            score: {
                bsonType: "array",
                minItems: 0,
                maxItems: 3,
                uniqueItems: true,
                description: "must be an array and is required",
                items: {
                    bsonType: "int",
                    description: "each element must be an integer"
                }
            }
        }
    }
}

db.createCollection("foo1", { validator: validator_example, “validationLevel”: “strict”, “validationAction”: “error”})

This is a simple example, however, you can also add all the attributes available for a given field under the “items” section.

Daniel.