当字段不为空时创建部分索引

sme*_*sme 7 indexing mongodb

我正在尝试在字段上创建部分索引,但仅当该字段不为空时。换句话说,我希望能够让许多文档能够存储空值,但是对于在该字段中实际具有值的文档,我希望该值是唯一的。这是我尝试使用的代码

db.account.createIndex({ "email": 1 }, { unique: true, partialFilterExpression: { "email": { $ne: null } }})
Run Code Online (Sandbox Code Playgroud)

根据我的理解,email当它不等于空时,这应该索引该字段。

但它给出了错误:

"unsupported expression in partial index: $not email $eq null"
Run Code Online (Sandbox Code Playgroud)

我尝试更改$ne: null为$exists: true,但是已经有多个文档的电子邮件字段值为空,因此它也引发了错误。我的架构有一个用于文档的电子邮件字段,所以每个文档都会自动有一个email字段,这意味着$exists: true无论如何都不会工作。

只有在字段不为空时才能索引字段的任何帮助都会很棒。

tur*_*hal 6

在$ne不支持的表达式运算符,

根据MongoDB 部分索引支持的表达式有:等式表达式(即字段:值或使用$eq运算符)、$exists: true表达式、$gt、$gte、$lt、$lte表达式、$type表达式、$and运算符仅在顶级,

您可以使用$type的检查方法是string这样的{ "email": { $type: "string" } },因为空类型是“空”。

笔记:

如部分索引的查询覆盖文档所述:


因为如果使用索引导致不完整的结果集,MongoDB 将不会使用部分索引进行查询或排序操作。

要使用部分索引,查询必须包含过滤器表达式(或指定过滤器表达式子集的修改过的过滤器表达式)作为其查询条件的一部分。

前任。要对$type过滤器使用部分索引,您必须使用以下过滤器:

{ "email": { "$eq": "foo@mail.com", "$type": "string" } }
// or
{ $and: [{ "email": "foo@mail.com" }, { "email": { $type: "string" } }] }
Run Code Online (Sandbox Code Playgroud)

操场

  • 请注意,如果使用 `{ "email": { $type: "string" } }` 部分过滤表达式,如果您的查询类似于 `{ email: "foo" }`,MongoDB 将无法使用它。这是因为这也会将带有电子邮件的文档作为包含“foo”的数组进行匹配。要解决这个问题,您需要像这样查询:`{ email: { $eq: "foo", $type: "string" } }` (4认同)