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

标签 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 添加 vtidator 时,它会失败。

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

最佳答案

我创建了一个类似的函数

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

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

就我而言,我从其他迁移模块获取它并需要。例如

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

希望对您有所帮助。

关于node.js - 如何通过 node.js mongodb 驱动程序将验证器添加到现有集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52350988/

相关文章:

mongodb - 对嵌套的对象数组进行排序

node.js - 使用 Firebase Auth 和 Express 验证社交登录?

node.js - 如果postgresql中不存在如何删除

mysql - 我应该在 Node.js (Express) 应用程序中的什么地方定义我的 MySQL 客户端?

javascript - 如何在 Mongoose 发布更新中间件期间访问更新的文档?

node.js - 同时填充多个字段

javascript - 从对象javascript读取

javascript - ECMAScript 6 支持 node.js 及其不同的包,例如原生的express body_parser

node.js - 断言流

MongoDb 连接被拒绝