Owner_id field does not pass validation error. What is wrong with my schema? - mongodb-stitch

I am looking into what is wrong with my schema. I'm attempting to insert an entry into my collection and I have gotten a slew of errors as I've changed things around but this seems to be the closest I have gotten to successfully inserting a document. I am using the mongodb-stitch-browser-sdk in a React Ionic project and I have a valid user logged in.
I am using the StitchUser.id which is a string as my owner_id (matches the id of my valid user in users collection).
Here is my schema followed by the error in Stitch logs. I was simply trying to insert a document to my Goals table. Also, there are no filters on this collection and there is only one role with the following rule.
{
"owner_id": "%%user.id"
}
This gives the user read and write permissions on the collection's that they created.
{
"bsonType": "object",
"required": [
"goalTitle",
"startDate",
"endDate",
"owner_id"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"owner_id": {
"bsonType": "string",
"validate": {
"%or": [
{
"%%prevRoot.owner_id": {
"%exists": false
}
},
{
"%%prevRoot.owner_id": "%%this"
}
]
}
},
"goalTitle": {
"bsonType": "string",
"minLength": {
"$numberInt": "1"
},
"maxLength": {
"$numberInt": "30"
}
},
"goalDescription": {
"bsonType": "string",
"minLength": {
"$numberInt": "0"
},
"maxLength": {
"$numberInt": "600"
}
},
"startDate": {
"bsonType": "string"
},
"endDate": {
"bsonType": "string"
}
}
}
Error:
role "owner" in "todo_list.Goals" does not have insert permission for document with _id: ObjectID("5e6aa8d11d233536e3ea8604"): could not validate document:
owner_id: Does not pass validation
Stack Trace:
StitchError: insert not permitted
Details:
{
"serviceAction": "insertOne",
"serviceName": "mongodb-atlas",
"serviceType": "mongodb-atlas"
}
{
"arguments": [
{
"collection": "Goals",
"database": "todo_list",
"document": {
"goalTitle": "Test Goal",
"goalDescription": "Test Description",
"endDate": "2020-03-11",
"startDate": "2020-03-10",
"owner_id": "5e6891382e6039c1c32f7d46",
"_id": {
"$oid": "5e6aa8d11d233536e3ea8604"
}
}
}
],
"name": "insertOne",
"service": "mongodb-atlas"
}
I've created another collection with no schema and the same rule checking for owner_id and documents in that collection are able to be inserted just fine. I'd have to imagine it is a schema error.

Related

Swagger 3.0 reDoc Discriminator JSON

I'm currently writing swagger 3.0 documentation and using reDoc to render as nice UI for it. I have a few scenarios in my documentation where based on a previous properties enum I would want to display different schema object properties. Sadly I cant seam to figure out how to wire this together properly in my documentation. So far I have the following test endpoint:
{
"post": {
"operationId" : "test",
"summary": "test",
"description": "test",
"tags": [ "test" ],
"consumes": "application/json",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "./schemas/test1.json"
},
{
"$ref": "./schemas/test2.json"
}
],
"discriminator": {
"propertyName": "pet_type",
"mapping": {
"click": "./schemas/test1.json",
"open": "./schemas/test2.json"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Success"
}
}
}
}
The test1.json looks like this:
{
"Cat": {
"type": "object",
"properties": {
"pet_type": {
"type": "string"
},
"hunts": {
"type": "boolean"
},
"age": {
"type": "integer"
}
},
"discriminator": {
"propertyName": "pet_type"
}
}
}
And the test2.json like this:
{
"Dog": {
"type": "object",
"properties": {
"pet_type": {
"type": "string"
},
"bark": {
"type": "boolean"
},
"breed": {
"type": "string",
"enum": [
"Dingo",
"Husky",
"Retriever",
"Shepherd"
]
}
},
"discriminator": {
"propertyName": "pet_type"
}
}
}
The desired out come would be to toggle between the two "test" jsons based on an enum (the drop down seen in the reDoc sample). What am I missing to get this result?
You can see an example of the discriminator result here under the feature section (the first gif)
After more digging I was able to figure out the issue... my structure for the most part.
On my index.json file I updated my components section to point at my components folder containing the schema as such:
"components": {
"$ref": "./components/test.json"
},
The test.json looks like the following:
{
"schemas": {
"Refinance": {
"description": "A representation of a cat",
"allOf": [
{
"$ref": "#/schemas/Pet"
},
{
"type": "object",
"properties": {
"huntingSkill": {
"type": "string",
"description": "The measured skill for hunting",
"default": "lazy",
"enum": [
"clueless",
"lazy",
"adventurous",
"aggressive"
]
}
},
"required": [
"huntingSkill"
]
}
]
},
"Purchase": {
"description": "A representation of a dog",
"allOf": [
{
"$ref": "#/schemas/Pet"
},
{
"type": "object",
"properties": {
"packSize": {
"type": "integer",
"format": "int32",
"description": "The size of the pack the dog is from",
"default": 1,
"minimum": 1
},
"foobar": {
"type": "string",
"description": "some ol bullshit"
}
},
"required": [
"packSize"
]
}
]
},
"Pet": {
"type": "object",
"discriminator": {
"propertyName": "petType"
},
"properties": {
"petType": {
"description": "Type of a pet",
"type": "string"
}
},
"xml": {
"name": "Pet"
}
}
}
}
And finally the schema for the endpoint gets referenced as follows:
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "../../index.json#/components/schemas/Pet"
}
}
}
},

ElasticSearch: Indexing with multiple mapping types

I am trying to fully comprehend indexing with multiple mapping types in ElasticSearch. In the docs it gives example code:
PUT my_index
{
"mappings": {
"user": {
"_all": { "enabled": false },
"properties": {
"title": { "type": "string" },
"name": { "type": "string" },
"age": { "type": "integer" }
}
},
"blogpost": {
"properties": {
"title": { "type": "string" },
"body": { "type": "string" },
"user_id": {
"type": "string",
"index": "not_analyzed"
},
"created": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
}
}
}
}
With this mapping how would I then create and search on an object?
For create would it be:
POST my_index/user/blogspot
or
POST my_index/user,blogspot
For searching would it be:
GET my_index/user/blogspot
or
GET my_index/user,blogspot
or something else?
An example of a POST and GET with multiple mapping would really help me out. Thank you so much!

How can I describe complex json model in swagger

I'm trying to use Swagger to describe web-api I'm building.
The problem is that I can't understand how to describe complex json object?
For example, how to describe this objects:
{
name: "Jhon",
address: [
{
type: "home",
line1: "1st street"
},
{
type: "office",
line1: "2nd street"
}
]
}
Okay, so based on the comments above, you want the following schema:
{
"definitions": {
"user": {
"type": "object",
"required": [ "name" ],
"properties": {
"name": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"$ref": "#/definitions/address"
}
}
}
},
"address": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [ "home", "office" ]
},
"line1": {
"type": "string"
}
}
}
}
}
I've made a few assumptions to make the sample a bit more complicated, to help in the future.
For the "user" object, I've declared that the "name" field is mandatory. If, for example, you also need the address to be mandatory, you can change the definition to "required": [ "name", "address" ].
We basically use a subset of json-schema to describe the models. Of course not everyone knows it, but it's fairly simple to learn and use.
For the address type you can see I also set the limit to two options - either home or office. You can add anything to that list, or remove the "enum" entirely to remove that constraint.
When the "type" of a property is "array", you need to accompany it with "items" which declares the internal type of the array. In this case, I referenced another definition, but that definition could have been inline as well. It's normally easier to maintain that way, especially if you need the "address" definition alone or within other models.
As requested, the inline version:
{
"definitions": {
"user": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"home",
"office"
]
},
"line1": {
"type": "string"
}
}
}
}
}
}
}
}

ElasticSearch: Multi field "upgrade" yields error:

Okay, here is the task:
I've already read the whole documentation and I noticed that I can "upgrade" a data type like string to a multi field - in a test scenario it already worked.
My documents structure is currently:
{
"name": "test",
"words": [
{
"words": "hello world",
"verts": [
1,
2,
3
]
}
]
}
These documents were created using the default mappings - so no mapping has been set explicitly.
I am issuing a XDELETE command with data like:
{
"article": {
"properties": {
"words": {
"type": "multi_field",
"fields": {
"words": {
"type": "string",
"index": "analyzed"
},
"untouched": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
But I receive this error here:
{"error":"MergeMappingException[Merge failed with failures {[Can't
merge a non multi_field / non simple mapping [words] with a
multi_field mapping [words]]}]","status":400}
Can someone explain to me, why this happens? When I issue this mapping to a clean index, it works and the not_analyzed filter is being applied.
Thanks :)
Jan
Because the "words" field in your document has properties of its own ("words" and "verts"), you can't "upgrade" it to a multi_field. However, if you had a mapping like
{
"article": {
"properties": {
"words": {
"properties": {
"words": {
"type": "multi_field",
"fields": {
"words": {
"type": "string",
"index": "analyzed"
},
"untouched": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
}
then everything should work out.

How do I use the swagger models section?

Inside the Swagger API Documentation there is inside the json beside the apis array a model object entry but no documentation about it. How can I use this "models" part?
{
apiVersion: "0.2",
swaggerVersion: "1.1",
basePath: "http://petstore.swagger.wordnik.com/api",
resourcePath: "/pet.{format}"
...
apis: [...]
models: {...}
}
Models are nothing but like your POJO classes in java which have variables and properties. In models section you can define your own custom class and you can refer it as data type.
If you see below
{
"path": "/pet.{format}",
"description": "Operations about pets",
"operations": [
{
"httpMethod": "POST",
"summary": "Add a new pet to the store",
"responseClass": "void",
"nickname": "addPet",
"parameters": [
{
"description": "Pet object that needs to be added to the store",
"paramType": "body",
"required": true,
"allowMultiple": false,
"dataType": "Pet"
}
],
"errorResponses": [
{
"code": 405,
"reason": "Invalid input"
}
]
}
Here in parameter section it have one parameter who's dataType is Pet and pet is defined in models as below
{
"models": {
"Pet": {
"id": "Pet",
"properties": {
"id": {
"type": "long"
},
"status": {
"allowableValues": {
"valueType": "LIST",
"values": [
"available",
"pending",
"sold"
]
},
"description": "pet status in the store",
"type": "string"
},
"name": {
"type": "string"
},
"photoUrls": {
"items": {
"type": "string"
},
"type": "Array"
}
}
}
}}
You can have nested models , for more information see Swagger PetStore example
So models are nothing but like classes.

Resources