mongoose 修复了唯一且稀疏且可以取空值的索引

ram*_*n22 2 mongoose mongodb node.js

我找到的大多数答案都来自旧帖子,我看到了部分索引,但没有关于如何使用它的好例子,而且当我再次启动 mongoose 时我启动了我的索引,但找不到关于如何设置它以使用部分索引的例子。

// db is read from a config file
mongoose.connect(db.uri, {autoIndex: db.autoIndex, useNewUrlParser: true});
Run Code Online (Sandbox Code Playgroud)

如果我希望像电子邮件这样的属性也是可选的并且是唯一的并被索引,但是当我将其设置更新为 null 或空白时,即使我强制它未定义也会导致重复错误。

这是我想出的解决方案,但他们有更好的方法,这是我所有荣耀的简化模型

let UserSchema = new mongoose.Schema({
  email: {
    type: String,
    lowercase: true,
    trim: true,
    index: {unique: true, sparse: true}
  }
});
// this run when creating a new user
UserSchema.pre('save', function (next) {
  if (this.email === null || this.email === '') {
    this.email = undefined;
  }
  next();
});
 // this runs when updating a user
UserSchema.pre('update', function () {
  const update = this.getUpdate();
  let fix = {};
  if (update.email === null || update.email === '') {
    delete this._update.email;
    fix.email = true;
  }
  this.update({}, {$unset: fix});
});
// Also what about findOneAndUpdate method will I need a pre method too
Run Code Online (Sandbox Code Playgroud)

ram*_*n22 6

在深入挖掘之后,我终于解决了它,使用部分索引并为空字符串的情况设置了一个函数,这将引发重复错误,因此空值对于未定义的值可以正常工作并且将被认为是唯一的

let UserSchema = new mongoose.Schema({
  email: {
    type: String,
    lowercase: true,
    trim: true,
    index: {
      unique: true,
      partialFilterExpression: {email: {$type: 'string'}},
    },
    set: v => (v === '' ? null : v)
  }
}); 
Run Code Online (Sandbox Code Playgroud)