Frequently updating "large" fields in MongoDB - mongodb

Let's say i have a collection that looks like this
$jsonSchema: {
bsonType: "object",
required: [ "Author", "Draft"],
properties: {
Tittle: {
bsonType: "string",
},
LastUpdated: {
bsonType: "date",
},
Author: {
bsonType: "string",
},
Draft: {
bsonType: "string"
}
}
}
The tittle, Publisher and Author fields, are almost never changed
The draft field can get "large" with thousands of words, when the author is working on it, it constantly(every few seconds if changed) saves the draft version to the Database
What would be the effective options for me?

Related

Trying ti edit a document via MongoDB Compass. What should I type for a key that has data type "bson date"?

Doc looks like this (simplified)
{
"_id": {
"$oid": "62112eed1ccb3f211c1b7116"
},
"joinDate": 1412180887
}
Validation schema
{
$jsonSchema: {
bsonType: 'object',
required: [ 'joinDate' ],
properties: {
joinDate: {
bsonType: 'date'
}
}
}
}
Not sure what I should type when I edit the field joinDate manually
the above value (integer) fails

How can I use regex in pattern for MongoDB `$jsonShema`?

{
$jsonSchema: {
bsonType: "object",
required: ["firstName", "lastName", "email", "destination"],
properties: {
firstName: {
bsonType: "string",
description: "First name is required!"
},
lastName: {
bsonType: "string",
description: "Last name is required!"
},
email: {
bsonType: "string",
pattern: "^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$",
description: "Email is required"
},
destination: {
bsonType: "string",
description: "Destination is require!"
}
}
}
}
In the above $jsonSchema, I attempt to use pattern as part of the schema specification
However, me existing ✉️ data fails validation inside of Compass.
This same pattern works just fine on client-side ReactJS form validation, so IK that the pattern itself is good.
However, something must be amiss with how we use this in $jsonSchema.
JSON Schema is encoded in JSON, and as such, strings need to be escaped.
This includes \ which must become \\, so where in your regex you have \., you need to escape it to become \\..
Having said that, as I don't have examples of your JSON data (and the email) you're trying to valid, I'm assuming what you've said is correct regarding the regular expression being sufficient for you elsewhere.

MongoDB $jsonSchema Validation Error in Compass - "Unknown $jsonSchema keyword"

I'm using Compass's validation tab to manually enter the $jsonSchema validation below.
Unfortunately it keeps showing the error "Unknown $jsonSchema keyword: geometry"
Not sure why this error is showing, since geometry is being used as a key.
Any advice on how I can correct this please?
{
$jsonSchema: {
bsonType: "object",
required: ["properties.Name", "properties.Country", "geometry.type", "geometry.coordinates"],
properties:{
Country: {
bsonType: "string",
description: "Must be supplied"
},
Name: {
bsonType: "string",
description: "Must be supplied"
},
description: {
bsonType: "string",
description: "Optional description"
}
},
geometry: {
type: {
bsonType: "string",
enum: ["Point"],
description: "Must be Point"
},
coordinates: {
bsonType: ["double"],
description: "Longitude, Latitude"
}
},
datePosted: {
bsonType: "date",
description: "Auto-added field"
},
image: {
bsonType: "string",
description: "URL of image location"
}
}
}
The JSON Schema you have supplied doesn't look quite right. The error about the unknown "geometry" keyword is because that attribute should describe one of your properties. The structure of the JSON Schema file is rigid and follows a tight (but admittedly confusing) spec.
I see a few things wrong with the schema you supplied:
The array of required properties should list the keys within the
properties object. So in your case, it should be something like
required: ["Name", "Country", "geometry"]
The geometry, datePosted, and image objects need to be placed inside the properties object.
The description of the geometry object must itself be another JSON Schema (it's a recursive pattern).
What is the geometry type? You have defined it as a string and as an enum with only one possible option ("Point"). Enum's only make sense if you provide multiple options, and their values would supersede the data type specified.
The code below is tested on MongoDB Compass:
{
$jsonSchema: {
bsonType: 'object',
required: [
'properties.Name',
'properties.Country',
'geometry.type',
'geometry.coordinates'
],
properties: {
Country: {
bsonType: 'string',
description: 'Must be supplied'
},
Name: {
bsonType: 'string',
description: 'Must be supplied'
},
description: {
bsonType: 'string',
description: 'Optional description'
},
geometry: {
type: 'object',
properties: {
type: {
'enum': [
'Point'
],
description: 'Must be Point'
},
coordinates: {
bsonType: [
'object'
],
description: 'Contains Longitude, Latitude',
properties: {
longitude: {
type: 'number',
description: 'Decimal representation of longitude'
},
latitude: {
type: 'number',
description: 'Decimal representation of latitude'
}
}
}
}
},
datePosted: {
bsonType: 'date',
description: 'Auto-added field'
},
image: {
bsonType: 'string',
description: 'URL of image location'
}
}
}
}
Have a look at the example in the docs: https://docs.mongodb.com/manual/core/schema-validation/
geometry is innerjson object so you need to mention what type of this innerjson object
geometry:{
bsonType:'object'} then mention required fields

MongoDB Linking a $jsonSchema to another $jsonSchema

I have two schemas with 1 to N relation. one is book and the other author.
I have crated three files names: book.js, genre.js and author.js below. As you see, I have referenced in the book the genre and author from other files.
author: {
$ref: "./models/author.js"
},
and
"genre" : {
$ref: "./models/genre.js",
description: "must be a string and is required"
}
However, When I issue that in mongo> i get the following:
{
"ok" : 0,
"errmsg" : "$jsonSchema keyword '$ref' is not currently supported",
"code" : 9,
"codeName" : "FailedToParse"
}
I was wondering How I could do that please?
// book.js
var book = {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "title", "author", "summary", "isbn", "genre" ],
properties: {
title: {
bsonType: "string",
description: "must be a string and is required"
},
author: {
$ref: "./models/author.js"
},
isbn: {
bsonType: "int",
minimum: 2017,
maximum: 3017,
exclusiveMaximum: false,
description: "must be an integer in [ 2017, 3017 ] and is required"
},
"summary" : {
bsonType: "string",
description: "must be a string and is required"
},
"genre" : {
$ref: "./models/genre.js"
}
}
}
}
};
module.exports = book;
//genre.js
var genre = {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "name"],
properties: {
first_name: {
bsonType: "string",
size: 100,
description: "must be a string and is required"
},
url: {
bsonType: "string",
minLength:3,
maxLength:20,
description: "must be a string and size between [3, 100] is not required"
}
}
}
}
};
module.exports = genre;
//author.js
var Author = {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "first_name", "family_name" ],
properties: {
first_name: {
bsonType: "string",
maxLength:100,
description: "must be a string and is required"
},
family_name: {
bsonType: "string",
maxLength:100,
description: "must be a string and is not required"
},
date_of_birth: {
bsonType: "int",
minimum: 0,
maximum: 2018,
exclusiveMaximum: false,
description: "must be an integer in [ 0, 3017 ] and is required"
},
date_of_death: {
bsonType: "int",
minimum: 0,
maximum: 2018,
exclusiveMaximum: false,
description: "must be an integer in [ 0, 2018 ] and is required"
}
}
}
}
};
module.exports = Author;
It seems the Manual References does not work:
$jsonSchema: {
bsonType: "object",
required: [ "title", "author_id", "summary", "isbn", "genre" ],
properties: {
title: {
bsonType: "string",
description: "must be a string and is required"
},
author_id: {
bsonType: ObjectId(),
description: "must be a string and is required"
},
isbn: {
as
{
"ok" : 0,
"errmsg" : "$jsonSchema keyword 'bsonType' must be either a string or an array of strings",
"code" : 14,
"codeName" : "TypeMismatch"
}
"$jsonSchema keyword '$ref' is not currently supported",
As per the error message you encountered, the implementation of JSON Schema does not (as at MongoDB 4.0) support references ($ref). Since $jsonSchema is being validated on the database server a relative file path isn't appropriate; you should instead inline the required schema validation rules.
If you want more flexibility you could look for a validation library you can use in your application code. There are several JSON Schema packages on NPM as well as alternative approaches such as Object-Document Mappers (for example, Mongoose).
It seems the Manual References does not work
bsonType: ObjectId(),
The ObjectId() usage here isn't valid JSON. You need to specify a string value with the BSON type: bsonType: "objectId".
For more information see $jsonSchema Extensions and Omissions in the MongoDB documentation for your server version.
Thank you very much. bsonType: "objectId". To be honest with you, I don't like using Mongoose. Using manual referencing:
original_author_id = ObjectId()
db.author.insert({
"_id": original_author_id,
first_name: "ghadamali",
family_name: "sarami",
date_of_birth: NumberInt(1944)
});
original_genre_id = ObjectId()
db.genre.insert({
"_id": original_genre_id,
name: "action",
url: "www.action.com"
});
db.book.insert({
title:"az range gol",
author_id: original_author_id,
summary: "shekle senasi shahname",
isbn: NumberInt(12312),
genre:original_genre_id
});

Mongo 3.6 debug validation using jsonSchema

I'm following a course from mongodb university to learn new features in the release 3.6, and I'm unable to resolve why my validator is invalid.
This is how I created the collection:
db.getSiblingDB("TSA").createCollection("claims", {
validator: {
$jsonSchema: {
bsonType: "object",
properties: {
_id: { },
airportCode: { type: "string", minLength: 3 },
airportName: { type: "string" },
airlineName: { type: "string", minLength: 5 },
claims: {
bsonType: "object",
properties: {
itemCategory: { bsonType: "array", maxItems: 3 },
amount: { type: "string", pattern: "^\$.*" }
}
}
},
required: ["airportCode", "airlineName", "claims"],
additionalProperties: false
}
}
})
Then, I try to insert this object:
db.getSiblingDB("TSA").claims.insertOne({
"airportCode": "ABE",
"airportName": "Lehigh Valley International Airport, Allentown",
"airlineName": "MongoAir",
"claims": {
"claimType": "Property Damage",
"claimSite": "Checked Baggage",
"itemCategory": [ "Sporting Equipment & Supplies" ],
"amount": "$180.00"
}
})
Getting the following error:
WriteError({
"index" : 0,
"code" : 121,
"errmsg" : "Document failed validation",
"op" : {
"_id" : ObjectId("5a705318d3d6c18337f07282"),
"airportCode" : "ABE",
"airportName" : "Lehigh Valley International Airport, Allentown",
"airlineName" : "MongoAir",
"claims" : {
"claimType" : "Property Damage",
"claimSite" : "Checked Baggage",
"itemCategory" : [
"Sporting Equipment & Supplies"
],
"amount" : "$180.00"
}
}
})
My question is, is there some way to debug the validator like "property X must be Y type" instead of getting a generic "Document failed validation"?
As of MongoDB 3.6, there is no feedback mechanism that would inform what part of a document failed validation during a server-side check. A corresponding feature request is open: SERVER-20547: Expose the reason an operation fails document validation. For now, it is left to the application code to perform its own validation if detailed feedback is required.
If you use regex pattern string, backslash itself must be escaped too:
db.getSiblingDB("TSA").createCollection("claims", {
validator: {
$jsonSchema: {
bsonType: "object",
properties: {
_id: { },
airportCode: { type: "string", minLength: 3 },
airportName: { type: "string" },
airlineName: { type: "string", minLength: 5 },
claims: {
bsonType: "object",
properties: {
itemCategory: { bsonType: "array", maxItems: 3 },
amount: { type: "string", pattern: "^\\$.*" }
}
}
},
required: ["airportCode", "airlineName", "claims"],
additionalProperties: false
}
}
})