如何在mongodb中限制父节点的最大引用 [英] How to limit maximum reference of the parental node in mongodb

查看:59
本文介绍了如何在mongodb中限制父节点的最大引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须用mongodb和官方文档建议的四种方法(父母参考,孩子参考,祖先数组,物化路径,嵌套集)创建树结构,我决定使用array of ancestors,因为树的层次将很深,可能达数千个级别或更多.因此,我认为通过查找节点的所有父节点所需的查询更少,可以通过更快的速度来弥补存储方面的损失.

I have to create a tree structure with mongodb and of the four methods suggested by the official doc (parental reference, child reference, array of ancestors, materialized paths, nested sets) I have decided to use array of ancestors because the tier of the tree will be quite deep potentially thousands of levels or more. So I thought the penalty in storage could be compensated by faster speed due to less query being required when looking for all the parents of a node.

问题在于树必须严格地是二进制的.因此,例如,节点1仅将节点2和节点3作为其子节点,而没有更多子节点.不幸的是,我现在想到的唯一方法是在下一个文档中找到所有引用要引用的特定父级的文档,如果计数不超过2,则插入引用目标父级的文档.

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

显然,问题出在mongodb的多线程性质上,即使不是,查询引用目标父级的计数的请求也可能出现在扫描和插入前一文档之间,这将导致第三次插入如果已经有一个文档引用了目标父级.

Obviously the problem is the multithreaded nature of mongodb and even if it wasn't, the request to look up the count that references the target parent could come in between the scanning and insertion of the previous document which would cause a third insertion if there were one document already referencing the target parent.

在mongodb和服务器的多线程环境中,是否可以确保只有两个节点可以引用父节点?

Is there a way I can make sure that only two nodes can reference a parent node in multithreaded environment of both mongodb and the server?

推荐答案

如果使用的是mongo 3.6版,则可以在服务器端使用$jsonSchema启用架构验证

If you are using mongo version 3.6, you can enable schema validation using $jsonSchema at the server side

我们将根据验证模式对我们更新/插入的每个文档进行验证,如果验证失败,则会引发错误,并且不会对该文档进行任何修改

each document we update/insert will be validated against the validation schema, it the validation fails an error will be thrown and no modification will be made on the document

示例node收集模式

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

验证架构

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 })
> 

找到

> 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" }

插入无效的文档[儿童大小> 2]

insert with invalid document [children 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 a validation error

更新-尝试为_id数据库添加第三个子项,失败,并显示验证错误

update - trying to add 3rd child for _id Databases, failed with validation error

> 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
> 

请参考模式验证& jsonSchema 以获得更多选项,将验证添加到现有收集和处理验证失败

please refer schema-validation & jsonSchema for more options, adding validation to existing collection and handling validation failures

这篇关于如何在mongodb中限制父节点的最大引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆