【问题标题】:Add new Validator to Existing Collection将新验证器添加到现有集合
【发布时间】:2017-06-01 22:41:12
【问题描述】:

我正在尝试将新字段(日期类型的 LastLoginDate)添加到现有集合中。这是我的示例脚本:

db.createCollection( "MyTestCollection",
   { "validator": { "$or":
       [
          { "username": { "$type": "string" } },
          { "notes": { "$type": "string" } }
       ]
    }
   }
)

db.getCollectionInfos({name: "MyTestCollection"});
  [
     {
        "name" : "MyTestCollection",
        "options" : {
           "validator" : {
              "$or" : [
                 {
                    "username" : {
                       "$type" : "string"
                    }
                 },
                 {
                    "notes" : {
                       "$type" : "string"
                    }
                 }
              ]
           }
        }
     }
  ]

将新字段LastLoginDate : { $type: "date" } 添加到现有集合“MyTestCollection”的最佳方法是什么。

添加新文档或使用新字段更新现有集合可能会创建此字段。但我不确定如何在新字段上强制执行日期类型。添加新字段后,如果我再次执行以下命令,它不会显示新添加字段的类型验证器。

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    我“应该”可能会在您的问题中以一个误解作为前缀。事实上,MongoDB 与传统 RDBMS 的不同之处在于它是“无模式的”,而且您实际上根本不需要“创建字段”。所以这与“表模式”不同,在模式改变之前你不能做任何事情。然而,“验证”是另一回事,在撰写本文时也是“仍然”相对较新的功能。

    如果您想“添加验证规则”,那么有些方法取决于集合的当前状态。在任何一种情况下,实际上都没有“添加到”功能,而是将操作“替换”all 验证规则为新的要指定的规则。请继续阅读以了解其工作原理。

    现有文件

    集合中有现有文档的地方,如documentation 中所述

    现有文件

    您可以使用 validationLevel 选项控制 MongoDB 如何处理现有文档。

    默认情况下,validationLevelstrict,MongoDB 将验证规则应用于所有插入和更新。将 validationLevel 设置为 moderate 会将验证规则应用于满足验证条件的现有文档的插入和更新。对于中等级别,不检查对不满足验证标准的现有文档的更新是否有效。

    这个和下面的示例部分基本上是说除了.createCollection() 上的选项之外,您还可以使用文档修改现有集合,但应该“警惕”当前文档可能不符合要求的规则。因此,如果您不确定集合中的所有文档是否符合规则,请使用 "moderate"

    为了申请,您目前使用.runCommand() 方法发出设置验证规则的“命令”。这是上面段落中的“validationLevel”

    由于您已有规则,我们可以使用`.getCollectionInfos() 检索它们,然后添加新规则并应用:

    let validatior = db.getCollectionInfos({name: "MyTestCollection"})[0].options.validator;
    
    validator.$or.push({ "LastLoginDate": { "$type": "date" } });
    
    db.runCommand({
      "collMod": "MyTestCollection",
      "validator": validator,
      "validationLevel": "moderate"
    });
    

    当然,如前所述,如果您确信文档都满足条件,那么您可以应用 "strict" 作为默认值。

    空集合

    如果在这种情况下,集合实际上是“空的”,根本没有文档您可以“删除”集合,因为当前数据不重要,那么您可以简单地改变以上并使用.createCollection().drop()结合使用:

    let validatior = db.getCollectionInfos({name: "MyTestCollection"})[0].options.validator;
    
    validator.$or.push({ "LastLoginDate": { "$type": "date" } });
    
    db.getCollection("MyTestCollection").drop();
    
    db.createCollection( "MyTestCollection", { "validator": validator });
    

    【讨论】:

    • @NielLunn 感谢您提供详细信息。这对于像我这样有 RDBS 背景的人来说非常有用。
    • @annadurai 通常的想法是,当有人回答您的问题令您满意时,您 Accept the Answer 并在可能的情况下对其有用性进行投票。
    • @Niel Lunn,我已经接受了答案。感谢您的帮助。
    【解决方案2】:
    let previousValidator = db.getCollectionInfos({name: "collectionName"})[0].options.validator;
    # push the key to required array
    previousValidator.$jsonSchema.required.push("isBloodReportAvailable")
    
    let isBloodReportAvailabl = {"bsonType" : "bool", "description" : "must be an bool object and is optional" }
    # add new property to validator
    previousValidator1.$jsonSchema.properties['isBloodReportAvailable'] = isBloodReportAvailabl
    
    db.runCommand({
      "collMod": "collectionName",
      "validator": previousValidator,
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-03
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 2018-04-28
      相关资源
      最近更新 更多