一个字段可以为空的复合索引 MongoDB

Compound index where one field can be null MongoDB

如何在其中一个字段可能不存在或为空的 mongo 中创建复合索引?

例如在下面的文档中,如果我创建一个复合索引 name+age。在某些文档中 age 不存在或为 null 的情况下,我如何仍能实现这一点?

{
  name: "Anurag",
  age: "21",
},
{
  name: "Nitin",
},

您可以创建 partial Index 如下:

  db.contacts.createIndex(
   { name: 1 },
   { partialFilterExpression: { age: { $exists: true } } }
   )

解释:

根据文档,部分索引仅索引集合中满足指定过滤器表达式的文档。通过索引集合中文档的子集,部分索引具有较低的存储要求,并降低了索引创建和维护的性能成本。在这种特殊情况下,假设您的集合有 100k 个文档,但只有 5 个文档具有“年龄”字段,在这种情况下,部分索引将仅包含索引中的那 5 个字段优化索引存储 space 并提供更好的性能。

要让查询优化器选择此部分索引,查询谓词必须包含名称字段的条件以及年龄字段的 non-null 匹配项。

以下示例查询将能够使用索引:

 db.contacts.find({name:"John"})
 db.contacts.find({name:"John",age:{$gt:20}})
 db.contacts.find({name:"John",age:30})

以下示例查询是基于此索引的“覆盖查询”:

db.contacts.find({name:"John",age:30},{_id:0,name:1,age:1})

(此查询将非常高效,因为它 return 数据直接来自索引)

以下示例查询将无法使用索引:

db.contacts.find({name:"John",age:{$exists:false}})
db.contacts.find({name:"John",age:null})
db.contacts.find({age:20})

请注意,如果需要同时搜索年龄字段和姓名,需要进行一些分析,因为姓名字段具有很好的选择性,如果您只搜索,则不会使用该索引age ,也许一个不错的选择是仅在年龄字段上创建额外的 sparse/partial 索引,这样如果这是一个可能的搜索用例,您可以获取包含特定年龄联系人的列表。