Consider a very simple MongoDB schema like a personal details collection:
schema: {
name:'string',
address: [
{
zipcode: 'number'
}
]
};
The collection I intend to build to must be a collection with 2 fields: a name field of type string and an address field which is an nested array of object in which zip code key is mandatory .I don't bother if there are additional keys like 'door no' ,'city' etc present inside address field .I have written mongodb validator schema using query operators for this scenario in 3 ways :
First way :
db.createCollection("person_details_1",
{
validator:
{
$and:[
{address :{$type:'array',$type:'object'}},
{ address: { $elemMatch: { zipcode : {$type: 'number' ,$exists :true } } } },
{name :{$type :'string'}}
]
}});
Second way:
db.createCollection("person_details_2",
{
validator:
{
$and:[
{address :{$type:'array',$type:'object'}},
{'address.zipcode' : {$type : 'number'}},
{name :{$type :'string'}}
]
}});
Third way :
db.createCollection("person_details_3",
{
validator:
{
$and: [
{address :{$type:'array',$type:'object'}},
{ address: { $elemMatch: { zipcode : {$type :'number'} } , $exists :true } },
{name :{$type :'string'}}
]
}});
All the collections validate successfully for cases where 1) name filed is absent 2) address field is absent / it is wrong datatype 3)inserts record where name field and address array with one object having zipcode field. But the following case fails : If I try to insert an address filed having multiple objects validator checks only whether any one of the object has zipcode key and inserts it wherein the intention is that validator must loop through all objects in array and must check if the zipcode is present in each of the object present.To be more clear , the following code is accepted where i intend the following code to produce an error :
db.person_details_1.insert(
{
name: 'arav',
address:
[{
zipcode: 23213
},{
name: 'ewef'
}]
});
This record is inserted into collection but really I want an error message to thrown for it .The same happens with person_details_2 and person_details_3 as well.
P.S: I wish the solution to be with query validation operators and not with $jsonSchema.
$elemMatchoperator is required for "multiple" conditions on an array element.'address.zipcode'just looks to see if "ANY" array element satisfies that criteria. So there need be only "one". Contrary to what you might be thinking, "validation" is really just another form of MongoDB Query.$elemMatchfor multiple conditions on an array element. See also Specify Multiple Conditions for Array of Documents in the core documentation. I also suggest you actually run these through.find()before you save as a validator. As stated, these are in fact "queries", so you can verify it returns ( or does not return ) what is required beforehand.