如何通过node.js mongodb驱动程序将验证器添加到现有集合中?

时间:2018-09-16 04:37:54

标签: node.js mongodb

这是我要在现有集合中添加验证器的代码。

const { MongoClient } = require("mongodb")

const schema = {
  $jsonSchema: {
    bsonType: "object",
    additionalProperties: false,
    required: ["name"],
    properties: {
      _id: {
        bsonType: "objectId"
      },
      name: {
        bsonType: "string"
      }
    }
  }
}

const main = async () => {
  const client = await MongoClient.connect(
    "mongodb://localhost",
    { useNewUrlParser: true }
  )
  const db = client.db("t12")

  // await db.createCollection("test", { validator: schema })
  await db.createCollection("test")
  await db.admin().command({ collMod: "test", validator: schema })

  await db.collection("test").createIndex({ name: 1 }, { unique: true })

  await db.collection("test").insertOne({ name: "t1" })
  await db.collection("test").insertOne({ value: "t2" }) // should fail

  const all = await db
    .collection("test")
    .find({})
    .toArray()
  console.log(all)

  await client.close()
}

main().catch(err => console.error(err))

失败:

max7z@mbp t12__npm__mongodb (master)*$ node test/1.js
{ MongoError: ns does not exist
    at /Users/max7z/projects/t/t12__npm__mongodb/node_modules/mongodb-core/lib/connection/pool.js:581:63
    at authenticateStragglers (/Users/max7z/projects/t/t12__npm__mongodb/node_modules/mongodb-core/lib/connection/pool.js:504:16)
    at Connection.messageHandler (/Users/max7z/projects/t/t12__npm__mongodb/node_modules/mongodb-
  ok: 0,
  errmsg: 'ns does not exist',
  code: 26,
  codeName: 'NamespaceNotFound',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {} }
^C

如果我使用该模式创建集合,则可以使用该集合,但是当我尝试通过collMod添加vatidator时,它将失败。

如何通过collMod命令将验证器添加到现有集合中?

3 个答案:

答案 0 :(得分:1)

我创建了一个类似

的函数
const updateValidator = async (collectionName, newValidator) => {
    return db.command({
      collMod: collectionName,
      validator: newValidator,
      validationLevel: "moderate",
      validationAction: "warn"
   });
}

db.command的问题在于它取代了整个验证架构。因此,您需要访问集合的当前架构。由于我没有在nodejs库中找到函数db.getCollectionInfos,因此添加了将其作为参数传递的可能性。

就我而言,我是从其他需要迁移的模块中获得的。例如

const currentValidator = require("migration-file-where-I-defined-the-previous-schema").schema.validator;

在所需文件中,我具有一些初始模式,例如:

module.exports.schema = {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name"],
      properties: {
        name: {
          bsonType: "string",
          maxLength: 300,
          minLength: 3,
          description: "Must be a string and is required"
        },
        created: {
          bsonType: "date",
          description: "Date when it was created"
        },
        deleted: {
          bsonType: "date",
          description: "Date when it was deleted"
        }
      }
    },
  }
};

然后,我创建新架构的合并,这样就足够了。例如

  const updatedValidator = Object.assign({}, currentValidator);
  updatedValidator.$jsonSchema.properties.new_attribX = {
    enum: ["type1", "type2"],
    description: "State of the tenant related to its life cycle"
  };
  updatedValidator.$jsonSchema.required.push('new_attribX');

  updateValidator("mycollection", updatedValidator)
    .then(next)
    .catch(console.error);

这会将先前的架构替换为已应用更改的新架构。对我来说,这足够了,但是请记住,当您有需要用新数据更新的现有数据时,则需要使用

之类的东西来更新它们。
collection.updateMany({'new_attribX': {$exists : false}}, {$set: {'new_attribX': 'type1'}});

对于不具有该属性(new_attribX)的数据,应为它们添加这种初始默认值:type1

希望对您有帮助。

答案 1 :(得分:0)

我认为您应该使用Mongoose验证架构。请阅读有关月糖的信息。它是最好的。

答案 2 :(得分:0)

问题出在那一行:

await db.admin().command({ collMod: "test", validator: schema })

正确的方法:

await db.command({ collMod: "test", validator: schema })