How to limit max link of parent node in mongodb

I need to create a tree structure using the mongodbfour methods proposed by the official document (parent link, child link, ancestor array, materialized paths, nested sets). I decided to use array of ancestorsit because the level of the tree will be quite deep, perhaps thousands of levels or more. Therefore, I thought that the penalty in the repository could be offset by a faster speed due to the smaller number of queries required when searching for all node parents.

The problem is that the tree must be strictly binary. So, for example, node 1 will have only node 2 and node 3 as their children and no more. Unfortunately, the only way I can do this now is to find all the documents that reference the specific parent that I would like to refer to in the next document, and if the counter does not exceed 2, I insert the document referencing the target parent.

Obviously, the problem lies in the multi-threaded nature of mongodb, and even if it is not, a search request for a counter that refers to the target parent may be between scanning and pasting the previous document, which will lead to the third insertion if there is one document already referencing the target the parent.

Is there a way to make sure that only two nodes can refer to the parent node in a multi-threaded environment of both mongodb and server?

+6
source share
1 answer

If you are using mongo version 3.6, you can enable circuit validation using $jsonSchemaserver side

each document that we update / insert will be checked for compliance with the verification scheme, while verification will not be performed, and no modification will be made to the document.

sample nodecollection scheme

{
   _id : string,
   parent : [string, null],
   children : string[2]
}

verification scheme

db.createCollection("node", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: [ "_id" ],
         properties: {
            parent: {
               bsonType: ["string", "null"],
               description: "must be a string"
            },
            children: {
               bsonType: ["array"],
               items : { bsonType: ["string"] },
               minItems: 0,
               maxItems: 2,
               description: "must be a array of string and max is 2"
            }
         }
      }
   }
});

inserts [with valid documents]

> db.node.insert( { _id: "Books", children: [ "Programming" ], parent: null } )
WriteResult({ "nInserted" : 1 })
> db.node.insert( { _id: "Programming", children: [ "Databases", "Languages" ], parent: "Books" } )
WriteResult({ "nInserted" : 1 })
> db.node.insert( { _id: "Languages", children: [ ], parent: "Programming" } )
WriteResult({ "nInserted" : 1 })
> db.node.insert( { _id: "Databases", children: [ "MongoDB", "dbm" ], parent: "Programming" } )
WriteResult({ "nInserted" : 1 })
> db.node.insert( { _id: "MongoDB", children: [ ], parent: "Databases" } )
WriteResult({ "nInserted" : 1 })
> db.node.insert( { _id: "dbm", children: [ ], parent: "Databases" } )
WriteResult({ "nInserted" : 1 })
> 

find

> db.node.find()
{ "_id" : "Books", "children" : [ "Programming" ], "parent" : null }
{ "_id" : "Programming", "children" : [ "Databases", "Languages" ], "parent" : "Books" }
{ "_id" : "Languages", "children" : [ ], "parent" : "Programming" }
{ "_id" : "Databases", "children" : [ "MongoDB", "dbm" ], "parent" : "Programming" }
{ "_id" : "MongoDB", "children" : [ ], "parent" : "Databases" }
{ "_id" : "dbm", "children" : [ ], "parent" : "Databases" }

insert with invalid document [child size> 2]

> db.node.insert({_id : "1", children : ["c1", "c2", "c3"], parent : "p1"})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})
> 

insert failed with validation error

update - _id ,

> db.node.updateOne( { _id: "Databases"}, {$push : {children: [ "Oracle" ]}} )
2018-02-25T21:00:08.087+0530 E QUERY    [thread1] WriteError: Document failed validation :
WriteError({
    "index" : 0,
    "code" : 121,
    "errmsg" : "Document failed validation",
    "op" : {
        "q" : {
            "_id" : "Databases"
        },
        "u" : {
            "$push" : {
                "children" : [
                    "Oracle"
                ]
            }
        },
        "multi" : false,
        "upsert" : false
    }
})
WriteError@src/mongo/shell/bulk_api.js:466:48
Bulk/mergeBatchResults@src/mongo/shell/bulk_api.js:846:49
Bulk/executeBatch@src/mongo/shell/bulk_api.js:910:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1154:21
DBCollection.prototype.updateOne@src/mongo/shell/crud_api.js:572:17
@(shell):1:1
> 

schema-validation jsonSchema ,

+3

All Articles