“文档” 菜单
文档首页
/
MongoDB Manual
/ / /

复合通配符索引

在此页面上

  • 用例
  • 使用属性模式搜索
  • 行为
  • 通配符索引的一般注意事项
  • 复合通配符索引注意事项
  • 开始体验
  • 筛选字段 wildcardProjection
  • 使用辅助方法创建通配符索引
  • 了解详情

7.0 版本中的新增功能

MongoDB 支持在一个字段或一组字段上创建通配符索引。 一个复合索引有多个术语。复合通配符索引具有一个通配符术语和一个或多个附加索引术语。

重要

通配符索引不会取代基于工作负载的索引规划。

有关创建支持工作负载的索引的详细信息,请参阅创建索引以支持查询。

属性模式是搜索具有共同特征的文档的有用技术。

不幸的是,创建大量单独的索引来覆盖所有可能的查询的成本很高。 通配符索引是创建大量单个索引的良好替代方案,因为一个通配符索引可以有效地覆盖许多潜在的查询。

考虑如下模式:

{
tenantId: <Number>,
tenantRegion: <Number>,
customFields: {
addr: <String>,
name: <String>,
blockId: <Number>,
...
}
dateOpened: <Date>
}

您可能想要查询具有特定tenantId的租户的 customFields字段的各个方面。 您可以创建一系列单独的索引:

{ tenantId: 1, “customFields.addr": 1 }
{ tenantId: 1, “customFields.name": 1 }
{ tenantId: 1, “customFields.blockId": 1 }
...

这种方法很难维护,而且很可能会达到每个集合的最大索引数 (64)。

请改用复合通配符索引。 复合通配符索引更易于编写和维护,并且不太可能达到 64 个collection的限制。

此示例在salesData collection 上创建复合通配符索引:

db.runCommand(
{
createIndexes: "salesData",
indexes: [
{
key: {
tenantId: 1,
"customFields.$**": 1
},
name: "tenant_customFields"
}
]
}
)

通配符"customFields.$**"指定customFields字段中的所有子字段。 另一个术语tenantId不是通配符规范;它是标准字段规范。

要创建通配符索引,请使用标准索引创建命令:

  • 默认情况下,通配符索引会省略_id字段。 要将_id字段包含在通配符索引中,必须将其明确包含在wildcardProjection文档中。

    db.salesData.createIndex(
    { "$**" : 1 },
    { "wildcardProjection" :
    { "_id": 1, "customers.lastName": 1, "customers.FirstName": 1, }
    }
    )
  • 您可以在一个collection上创建多个通配符索引。

  • 通配符索引可能涵盖与collection中其他索引相同的字段。

  • 通配符索引很稀疏。 它们仅包括包含索引字段的文档的条目。

    如果复合通配符索引中的所有字段均缺失,则不会对文档编制索引。

  • 复合通配符索引是稀疏索引。

  • 如果文档缺少通配符字段但具有复合字段之一,则该文档将包含在索引中。

  • 索引字段(包括通配符字段)可以按升序 ( 1 ) 或降序 ( -1 ) 排序。

您可以使用wildcardProjection来指定各个子字段。

db.runCommand(
{
createIndexes: "salesData",
indexes: [
{
key: {
tenantId: 1,
"$**": 1
},
name: "tenant_customFields_projection",
wildcardProjection: {
"customFields.addr": 1,
"customFields.name": 1
}
}
]
}
)

通配符索引术语"$**"指定collection中的每个字段。wildcardProjection将索引限制为指定字段"customFields.addr""customFields.name"

wildcardProjection仅当通配符为$** 时,才能使用 。

MongoDB 为大多数 数据库命令 提供了 Shell 助手方法 。这些 shell 方法提供简化的语法,并且在功能上等同于数据库命令。

第一个示例的 shell 助手是:

db.salesData.createIndex(
{ tenantId: 1, "customFields.$**": 1 },
{
name: "tenant_customFields_shellHelper"
}
)

第二个示例的 Shell 助手是:

db.salesData.createIndex(
{ tenantId: 1, "$**": 1 },
{ "wildcardProjection": {
"customFields.addr": 1,
"customFields.name": 1
},
name: "tenant_customFields_projection_helper"
}
)

如果要比较 Shell 命令和数据库命令,必须删除命令调用之间的索引。 即使使用不同的名称,也不能两次创建相同的索引。

要删除索引,请插入索引名称并运行db.collection.dropIndex()。

db.salesData.dropIndex( "tenant_customFields" )

前面的命令会从salesData数据库中删除"tenant_customFields"索引。

← 对所有字段创建通配符索引