mongodb/ Mongoose : Save unique value if data is not null in from nestjs

标签 mongodb mongoose nestjs

我正在尝试将数据保存在 MongoDB 中。我想在数据不为空时存储唯一数据。但是,我想在唯一标识符中允许多个空值。

我的示例架构:

@Schema()
export class Contact extends Document {
  @Prop({ unique: true, sparse: true, require: true })
  email: string;
  
  @Prop({ default: '+1' })
  countryCode: string;

  @Prop({ unique: true, sparse: true })
  mobile: string;
}

在这种情况下,不需要手机号码。用户可以在提供或不提供手机号码的情况下添加联系信息。如果用户发送他们的手机号码,该号码应该是唯一的。因此,我需要在 mobile 字段中允许多个 null 值。但是,当用户提供任何手机号码时,该字段应该是唯一的。

空条目似乎会获取值 null,因此每个没有 mobile 的条目都会因 unique 标识符而崩溃。

有没有办法从数据库层或者应用层解决这个问题?

我正在使用 NestJS 来开发我的 API。

最佳答案

唯一索引仍然不允许多个文档的字段为空。在将文档保存到 MongoDB 之前,您需要通过删除 null 字段来转换数据负载。转换管道将帮助您处理这个问题。这是一个可用于此目的的转换管道:

@Injectable()
export class NullValidationPipe implements PipeTransform {
  private isObj(obj: any): boolean {
    return typeof obj === 'object' && obj !== null;
  }

  private dropNull(values) {
    Object.keys(values).forEach((key) => {
      if (!(key === 'password' || key === '_id')) {
        if (this.isObj(values[key])) {
          values[key] = this.dropNull(values[key]);
        } else if (Array.isArray(values[key]) && values[key].length > 0) {
          values[key] = values[key].map((value) => {
            if (this.isObj(value)) {
              value = this.dropNull(value);
            }
            return value;
          });
        } else {
          if (values[key] === null || values[key] === undefined) {
            delete values[key];
          }
        }
      }
    });
    return values;
  }

  transform(values: any, metadata: ArgumentMetadata) {
    const { type } = metadata;
    if (type === 'param' || type === 'custom') return values;
    else if (this.isObj(values) && type === 'body') {
      return this.dropNull(values);
    }

    throw new BadRequestException('Validation failed');
  }
}

在 Controller 中使用此管道,此管道将删除请求负载附带的所有传入空字段。

您还可以检查嵌套管道转换文档:https://docs.nestjs.com/techniques/validation

关于mongodb/ Mongoose : Save unique value if data is not null in from nestjs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70169805/

相关文章:

javascript - 在 Meteor 发布中通过 id 链接用户

C# Mongodb。所有文档的求和字段

node.js - 检索最近 6 分钟内所有 `date` 的内容

node.js - Mongoose 按填充字段排序

node.js - MongoDB 保存用户时电子邮件和密码无效

javascript - 将 TypeORM 存储库注入(inject) NestJS 服务以进行模拟数据测试

MongoDB 过滤器(如果所有键都作为字段存在)

mongodb - 如何在不超过最大文档大小的情况下编写聚合?

javascript - 无法在拦截器中取消请求

node.js - NestJS > TypeORM 将复杂实体映射到复杂 DTO