tl; dr
是的,null在强制执行唯一的“实际”值的同时,可能会有多个文档的字段设置为或未定义。
要求:
- MongoDB v3.2 +。   
- 事先了解您的具体价值类型(例如,始终为a string或object不为时null)。
如果您对这些细节不感兴趣,请随时跳到本implementation部分。
更长的版本
为了补充@Nolan的答案,从MongoDB v3.2开始,您可以使用带有过滤表达式的部分唯一索引。
部分过滤器表达式具有局限性。它只能包括以下内容:
  
  - 等式表达式(即字段:值或使用$eq运算符),
- $exists: true表达,
- $gt,- $gte,- $lt,- $lte表情,
- $type表达式,
- $and仅限顶级运营商
这意味着{"yourField"{$ne: null}}无法使用平凡的表达式。
但是,假设您的字段始终使用相同的类型,则可以使用$typeexpression。
{ field: { $type: <BSON type number> | <String alias> } }
MongoDB v3.6添加了对指定多种可能类型的支持,这些类型可以作为数组传递:
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
这意味着它允许在不允许的情况下使用多种类型中的任何一种null。
因此,如果我们要允许email以下示例中的字段接受一个值string或binary data一个值,则合适的$type表达式为:
{email: {$type: ["string", "binData"]}}
实施
猫鼬
您可以在猫鼬模式中指定它:
const UsersSchema = new Schema({
  name: {type: String, trim: true, index: true, required: true},
  email: {
    type: String, trim: true, index: {
      unique: true,
      partialFilterExpression: {email: {$type: "string"}}
    }
  }
});
或直接将其添加到集合中(使用本地的node.js驱动程序):
User.collection.createIndex("email", {
  unique: true,
  partialFilterExpression: {
    "email": {
      $type: "string"
    }
  }
});
本机mongodb驱动程序
使用 collection.createIndex
db.collection('users').createIndex({
    "email": 1
  }, {
    unique: true,
    partialFilterExpression: {
      "email": {
        $type: "string"
      }
    }
  },
  function (err, results) {
    // ...
  }
);
mongodb外壳
使用db.collection.createIndex:
db.users.createIndex({
  "email": 1
}, {
  unique: true, 
  partialFilterExpression: {
    "email": {$type: "string"}
  }
})
这将允许插入多个记录并附带null一封电子邮件,或者根本没有一个电子邮件字段,但不能插入相同的电子邮件字符串。