You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建MongoDB严格Schema:带任意字符串键与ObjectID数组值的TS接口

在Nest.js中创建严格匹配动态键值约束的MongoDB Schema

需求概述

需要创建一个MongoDB Schema,满足以下严格约束:

  • 文档的键必须是合法字符串(非数字形式的字符串)
  • 每个键对应的值必须是MongoDB ObjectID实例的数组
  • 拦截所有不符合约束的文档(如单ObjectID值、字符串数组、无效ObjectID、数字键等)

实现方案

利用Mongoose的自定义验证功能结合严格模式,实现对动态键值对的全面校验。以下是完整的TypeScript代码实现:

import { Schema, SchemaTypes, model, Document, ValidatorProps } from 'mongoose';

// 定义TypeScript类型,匹配Schema约束
interface DynamicObjectIDArrayDocument extends Document {
  [key: string]: Schema.Types.ObjectId[];
}

// 创建Schema并添加自定义验证逻辑
const dynamicObjectSchema = new Schema<DynamicObjectIDArrayDocument>({}, {
  // 严格模式:遇到未知属性直接抛出错误
  strict: 'throw',
  // 自定义文档级验证
  validate: {
    validator: function(doc: DynamicObjectIDArrayDocument) {
      const docObj = doc.toObject();
      // 遍历所有键值对,排除Mongoose内置属性
      for (const [key, value] of Object.entries(docObj)) {
        if (key === '_id' || key === '__v') continue;

        // 验证键:必须是字符串,且不能是可转换为数字的字符串
        if (typeof key !== 'string' || !isNaN(Number(key))) {
          return false;
        }

        // 验证值:必须是数组类型
        if (!Array.isArray(value)) {
          return false;
        }

        // 验证数组元素:每个元素必须是有效的ObjectID实例
        for (const item of value) {
          if (!(item instanceof SchemaTypes.ObjectId) || !SchemaTypes.ObjectId.isValid(item.toString())) {
            return false;
          }
        }
      }
      return true;
    },
    message: (props: ValidatorProps) => `文档验证失败:${props.path} 的键或值不符合约束`
  }
});

// 创建Nest.js中可注入的模型
export const DynamicObjectModel = model<DynamicObjectIDArrayDocument>('DynamicObject', dynamicObjectSchema);

验证逻辑说明

上述代码会自动拦截所有不合法的文档:

  1. 拦截单个ObjectID值(如invalidDocumentProperty_1):验证会检查值是否为数组,非数组直接返回false
  2. 拦截字符串数组(如invalidDocumentProperty_2):验证数组元素是否为ObjectID实例,字符串无法通过检查
  3. 拦截无效ObjectID字符串(如invalidDocumentProperty_3):通过SchemaTypes.ObjectId.isValid()验证字符串是否为合法ObjectID格式
  4. 拦截数字形式的键(如invalidDocumentProperty_4):检查键是否为非数字转换的字符串,数字键会被拦截

使用示例

在Nest.js服务中使用该模型时,不符合约束的创建操作会自动抛出验证错误:

// 合法文档:可以成功创建
await DynamicObjectModel.create({
  validKey: [SchemaTypes.ObjectId('4edd40c86762e0fb12000003')]
});

// 不合法文档:会触发验证错误
await DynamicObjectModel.create({
  validKey: SchemaTypes.ObjectId('4edd40c86762e0fb12000003')
}).catch(err => {
  console.error(err.message); // 输出:文档验证失败: 的键或值不符合约束
});

内容的提问来源于stack exchange,提问作者ENcy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:05:27