MongoDB jsonSchema validation additionalProperties - mongodb

Create Collection with validator
db.createCollection("claims",
{ validator : { $jsonSchema : { bsonType : "object",
properties : { airportCode : { bsonType: "string"} },
additionalProperties: false}
} } )
Insert
db.claims.insert({"airportCode" : "DSM"}) => result: "errmsg" : "Document failed validation"
if I remove "additionalProperties: false" by creating the collection, when I can insert the document.
Any advice, how to keep "additionalProperties: false", because I want to control the document.

As at MongoDB 3.6.2, JSON Schema validation does not automatically add the default _id property, so you need to include a rule for this when using additionalProperties: false.
For example, assuming the default ObjectID:
db.createCollection("claims",
{ validator : {
$jsonSchema : {
bsonType : "object",
properties : {
_id: { bsonType: "objectId" },
airportCode : { bsonType: "string"}
},
additionalProperties: false
}
}}
)
Two related issues to upvote/watch on the MongoDB Jira issue tracker:
SERVER-32160: provide warning when _id is not in list of properties and additionalProperties is false
SERVER-20547: Expose the reason an operation fails document validation

Related

Mongodb native validation for embedded documents

I'm trying to come up with a Mongodb's native validation rule that will validate a document (having an embedded document) such that either the embedded document is not present at all OR if present, it has one or more fields mandatorily present.
I have got an example below. A JSON document has an embedded document user. This user may not exist or when it exists it needs to have a field name mandatorily present.
"validator" : {
"$or" : [
{
"user" : {
"$exists" : "false",
"$type" : "null"
}
},
{
"user.name" : {
"$type" : "string",
"$exists" : "true"
}
}
]
}
And when I try to insert an empty JSON document to my collection testschema like db.testschema.insert({}), I get the standard error below which doesn't tell what is wrong and/or why. This should be possible because my document can either contain an embedded document user with a field name or not contain the embedded document at all.
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
Are the operators used inside the validator looking correct?
First thing null, true and false should not be passed as strings, false passed as the string will evaluate to true only.
Solution No need of "$type" : null validator, just "$exists" : false is enough for your case, The following validation will work for you
"validator" : {
"$or" : [
{
"user" : {
"$exists" : false,
}
},
{
"user.name" : {
"$type" : "string",
"$exists" : true
}
}
]
}

How do I validated array of objects using mongodb validator?

I have been trying to validate my data using the validators provided by MongoDB but I have run into a problem. Here is a simple user document which I am inserting.
{
"name" : "foo",
"surname" : "bar",
"books" : [
{
"name" : "ABC",
"no" : 19
},
{
"name" : "DEF",
"no" : 64
},
{
"name" : "GHI",
"no" : 245
}
]
}
Now, this is the validator which has been applied for the user collection. But this is now working for the books array which I am inserting along with the document. I want to check the elements inside the object which are the members of books array. The schema of the object won't change.
db.runCommand({
collMod: "users",
validator: {
$or : [
{ "name" : { $type : "string" }},
{ "surname" : { $type : "string" }},
{ "books.name" : { $type : "string" }},
{ "books.no" : { $type : "number" }}
],
validationLevel: "strict"
});
I know that this validator is for member objects and not for array, but then how do I validate such an object ?
It has been very long since this question was asked.
Anyways, if at all anyone comes through this.
For MongoDB 3.6 and greater version, this can be achieved using the validator.
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name","surname","books"],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
surname: {
bsonType: "string",
description: "must be a string and is required"
},
books: {
bsonType: [ "array" ],
items: {
bsonType: "object",
required:["name","no"],
properties:{
name:{
bsonType: "string",
description: "must be a string and is required"
},
no:{
bsonType: "number",
description: "must be a number and is required"
}
}
},
description: "must be a array of objects containing name and no"
}
}
}
}
})
This one handles all your requirements.
For more information, refer this link
You can do it in 3.6 using $jsonSchema expression.
JsonSchema allows defining a field as an array and specifying schema constraints for all elements as well as specific constraints for individual array elements.
This blog post has a number of examples which will help you figure out the syntax.

changing field in a set object in mongodb

I have this document in mongo:
{
id: objectId,
list: [
{
id: internalObjectId1,
enabled: true
},
{
id: internalObjectId2,
enabled: false
}]
}
I need to change the enabled field. How can I do it?
Use the positional $ operator. Suppose you have the following document in the collection whose list element value is an array of embedded documents:
{
"_id" : ObjectId("551be1a04db8a16ac729432e"),
"list" : [
{
"id" : ObjectId("54f43159c922ac0b4387ef9c"),
"enabled" : true
},
{
"id" : ObjectId("54f43159c922ac0b4387ef9d"),
"enabled" : false
}
]
}
The following will update the value of the enabled field in the embedded document with the id of 54f43159c922ac0b4387ef9d to true:
db.collection.update(
{
"_id": ObjectId("551be1a04db8a16ac729432e"),
"list.id": ObjectId("54f43159c922ac0b4387ef9d")
},
{
"$set": {"list.$.enabled": true}
}
)

update query in mongo db

I am using mongodb database to save the records.
This is one sample record:
"_id" : ObjectId("53870ed7e4b00e612650c1b8"),
"_class" : "mkcl.os.transformer.PayloadObject",
"formId" : NumberLong(50),
"dataMap" : {
"240" : "ramanbaug",
"241" : "1234",
"242" : "12345678",
"243" : "mr.joshi",
"244" : "8308009391 ",
"245" : "anuja2487#gmail.com",
"280" : "456",
"287" : "1234",
"276" : "29/05/14",
"247" : "No",
"248" : "No",
"249" : "Yes",
"250" : "No",
"251" : "Yes",
"252" : "No"
}
Now I want to update the value of field "241". I read about the Update and FindAndModify Query. But There is no error and records are not getting updated.
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
in the place of enter same query as you use to find that record(s), which you want to update
in the place of enter new values, like doing during insert query
and there are 3 more options:
upsert = Optional. If set to true, creates a new document when no document matches the query criteria. The default value is false, which does not insert a new document when no match is found. So if your doc will not be found you will create a new one
multi = Optional. If set to true, updates multiple documents that meet the query criteria. If set to false, updates one document. The default value is false. For additional information, see Multi Parameter.
writeConcern = Optional. A document expressing the write concern. Omit to use the default write concern.
you can read more about write concern here: http://docs.mongodb.org/manual/core/write-concern/
Single document update example:
db.people.update(
{ name: "Andy" },
{
name: "Andy",
rating: 1,
score: 1
},
{ upsert: true }
)
check out for upsert: true, so it will create new doc if none found by name=Andy
Multi documents update example:
db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
)
Example with your data:
db.people.update(
{ _id: ObjectId("53870ed7e4b00e612650c1b8") },
{
dataMap: {
"241": "321"
}
}
)
that should work.
It's all in official documentation:
http://docs.mongodb.org/manual/reference/method/db.collection.update/
db.payloadObject.update({"dataMap.241":'1234'},{$set :{"dataMap.241":'123456'}});

NULL fields document model

I'm new to elasticsearch and nosql document model in general.
In elasticsearch what is the best practice for fields that are null.
Should we declare it as null or leave it out completely?
Example: the email field
[{
id:1,
name:"John",
email:"userone#erj.com"
},
{
id:2,
name:"David",
email:null
},
{
id:3,
name:"Tony"
}]
What you want to do with the null field is completely up to you. By default, ES will completely ignore the null field. If you want, you can specify a default value in the mapping for the document for the null field as well.
mapping example:
{
"_default_" : {
"properties" : {
"id" : {"type" : "string", "index" : "not_analyzed"},
"name" : {"type" : "string"},
"email" : {"type" : "string", "index" : "not_analyzed", "null_value" : "NOEMAILAVAILABLE"}
}
}
}
The potential ways to handle this are outlined here: http://www.elasticsearch.org/guide/reference/mapping/core-types.html