Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs 菜单
Docs 主页
/ /

通配符索引限制

本页介绍了通配符索引的限制,例如不兼容的属性和不支持的查询模式。

复合通配符索引具有以下限制:

  • 复合通配符索引只能有一个通配符。

    示例,不能指定以下索引:

    { userID: 1, "object1.$**": 1, "object2.$**": 1 }
  • 复合通配符索引中的非通配符词语必须是单键词语。不允许使用多键索引术语。

  • 仅当通配符字段为 $** 时,才能指定 wildcardProjection 选项。为通配符索引索引字段路径(Field Path)术语,不能使用 wildcardProjection

    这是一个有效的定义:

    {
    key: { "$**": 1 },
    name: "index_all_with_projection",
    wildcardProjection: {
    "someFields.name": 1,
    "otherFields.values": 1
    }
    }

    这是无效的定义:

    {
    key: { "someFields.$**": 1 },
    name: "invalid_index",
    wildcardProjection: {
    "someFields.name": 1,
    "otherFields.values": 1
    }
    }
  • 默认情况下, _id字段被省略。 如果您需要_id字段:

    • 将通配符索引指定为 $**

    • 使用 _id: 1_id字段包含在 wildcardProjection 中。

    db.studentGrades.createIndex(
    {
    "$**": 1,
    },
    {
    wildcardProjection: {
    _id: 1,
    exams: 1,
    extraCredit: 1
    }
    }
    )
  • 通配符字段和常规字段不能包含相同的字段。要从通配符模式中排除字段,请使用带有排除规则的 wildcardProjection

    db.studentGrades.createIndex(
    {
    exams: 1,
    "$**": 1,
    homeworks: 1
    },
    {
    wildcardProjection: {
    exams: 0,
    homeworks: 0
    }
    }
    )

从MongoDB 8.3(以及 8.2.4、8.0.18、7.0.29)开始,更严格的验证规则应用于复合通配符索引中的 wildcardProjection,以防止无效配置。

不满足新验证要求的现有索引会继续运行,但无法创建不满足这些要求的新索引。

wildcardProjection 与复合通配符索引一起使用时,以下规则应用:

规则
有效示例
无效示例

如果指定 wildcardProjection,则不能为空。

{ productId: 1, "$**": 1 },
{
wildcardProjection: {
attributes: 1
}
}
{ productId: 1, "$**": 1 },
{
wildcardProjection: { }
}

仅当包含或排除的字段为 _id 时,才能在 wildcardProjection 中组合包含和排除。您可以在包含投影中排除 _id,或在排除投影中包含 _id

{ "$**": 1, category: 1 },
{
wildcardProjection: {
_id: 0,
attributes: 1
}
}
{ "$**": 1, category: 1 },
{
wildcardProjection: {
_id: 1,
metadata: 0
}
}
{ "$**": 1, category: 1 },
{
wildcardProjection: {
_id: 0,
price: 0,
stock: 1
}
}

wildcardProjection 中包含的字段不得与任何常规(非通配符)索引字段重叠。

{ userId: 1, "$**": 1 },
{
wildcardProjection: {
preferences: 1
}
}
{ userId: 1, "$**": 1 },
{
wildcardProjection: {
userId: 1
}
}

只有当常规索引字段也为 _id 时,才能指定仅排除 _id

{ _id: 1, "$**": 1 },
{
wildcardProjection: {
_id: 0
}
}
{ productId: 1, "$**": 1 },
{
wildcardProjection: {
_id: 0
}
}

如果 wildcardProjection 是排除项,则它必须排除所有常规索引字段。

{
userId: 1,
category: 1,
"$**": 1
},
{
wildcardProjection: {
userId: 0,
category: 0
}
}
{
userId: 1,
category: 1,
"$**": 1
},
{
wildcardProjection: {
userId: 0
}
}

不能为通配符索引指定以下属性:

不能使用通配符语法 ( $.** ) 创建以下索引类型:

注意

消歧

通配符索引与在自托管部署上创建通配符文本索引不同且不兼容。 通配符索引不支持使用$text操作符的查询。

不能将通配符索引用作分片键索引。

通配符索引不支持以下查询模式:

如果给定字段是集合中任何文档中的数组,则通配符索引不支持查询该字段不等于null的文档。

例如,考虑一个inventory集合,其通配符索引位于product_attributes上。 如果product_attributes.tags是集合中任何文档中的数组,则通配符索引支持以下查询:

db.inventory.find( { $ne : [ "product_attributes.tags", null ] } )
db.inventory.aggregate( [
{
$match : { $ne : [ "product_attributes.tags", null ] }
}
] )

通配符索引存储文档或大量内容的条目,而不是文档或大量本身。 因此,通配符索引不支持对文档或数组进行精确等值匹配。

示例,考虑一个inventory集合,其通配符索引位于product_attributes上。 通配符索引不支持以下查询:

db.inventory.find(
{
"product_attributes" : { "price" : 29.99 }
}
)
db.inventory.find(
{
"product_attributes.tags" : [ "waterproof", "fireproof" ]
}
)

注意

通配符索引可以支持字段等于空文档{}的查询。

同样,通配符索引不支持对文档和数组进行精确的不等式匹配。 例如, product_attributes上的通配符索引不能支持以下查询:

db.inventory.aggregate( [
{
$match : {
$ne : [ "product_attributes", { "price" : 29.99 } ]
}
}
] )
db.inventory.aggregate( [
{
$match : {
$ne : [ "product_attributes.tags", [ "waterproof", "fireproof" ] ]
}
}
] )

通配符索引比较稀疏,不会为空字段索引。 因此,通配符索引不支持查询不含字段的文档。

示例,考虑一个inventory集合,其通配符索引位于product_attributes上。 通配符索引不支持以下查询:

db.inventory.find(
{
"product_attributes" : { $exists : false }
}
)
db.inventory.aggregate( [
{
$match : {
"product_attributes" : { $exists : false }
}
}
] )

在单个通配符索引可以支持多个查询字段的情况下,MongoDB只能使用该通配符索引来支持其中一个查询字段。

示例,考虑一个inventory集合,其通配符索引位于product_attributes上。 通配符索引不能支持以下查询中的所有谓词:

db.inventory.find(
{
"product_attributes.price": { $gt: 20 },
"product_attributes.material": "silk",
"product_attributes.size": "large"
}
)

相反,MongoDB使用通配符索引仅支持其中一个查询谓词。MongoDB会根据相关通配符索引路径自动选择要支持的谓词。不支持的查询谓词显示在解释结果的rejectedPlans 中。

复合通配符索引也是如此。复合索引的通配符术语只能支持一个查询谓词,尽管非通配符术语可以支持其余谓词。

注意

$or 行为

MongoDB可以使用相同的通配符索引来支持查询$or或聚合$or操作符的每个独立参数。

仅当 以下所有条件为sort() true 时,MongoDB 才能使用通配符索引来满足 :

  • 查询规划器选择通配符索引来满足查询谓词。

  • sort()指定查询谓词字段。

  • 指定的字段绝不是数组。

如果不满足上述条件, MongoDB则无法使用通配符索引进行排序。 MongoDB不支持需要与查询谓词不同的索引的sort()操作。

请考虑 products 集合的以下通配符索引:

db.products.createIndex( { "product_attributes.$**" : 1 } )

以下操作查询单个字段product_attributes.price并对该字段进行排序:

db.products.find(
{ "product_attributes.price" : { $gt : 10.00 } },
).sort(
{ "product_attributes.price" : 1 }
)

假设指定的price绝不是数组,则 MongoDB 可以使用product_attributes.$**通配符索引来同时满足find()sort()

后退

签名

在此页面上