通配符索引限制

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

复合通配符索引限制

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

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

    例如,您不能指定以下索引:

    { userID: 1, "object1.$**": 1, "object2.$**": 1 }
    
  • a 中的非通配符术语compound wildcard index必须是单个关键术语。不允许使用多键索引项。

  • wildcardProjection仅当通配符字段为 时,该选项才有效$**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 字段:

    • 将通配符索引指定为$**
    • 用一个wildcardProjection
    • 指定_id字段
    db.studentGrades.createIndex(
       {
          "$**": 1,
       },
       {
          wildcardProjection: {
             _id: 1,
             exams: 1,
             extraCredit: 1
          }
       }
    )
    
  • 通配符字段和常规字段中不能包含相同的字段。您可以使用 awildcardProjection从通配符模式中排除字段。

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

不兼容的索引属性

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

不兼容的索引类型

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

笔记:

消歧义

通配符索引与创建通配符文本索引不同且不兼容 。通配符索引不支持使用$text运算符的查询。

片键

您不能使用通配符索引作为分片键索引。

不支持的查询模式

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

数组字段不等于null

如果给定字段是集合中任何文档中的数组,则通配符索引无法支持查询该字段不等于 的文档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" ]
   }
)

笔记:

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

同样,通配符索引不能支持文档和数组上的精确不等式匹配。例如,通配符索引 on 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 不能使用非通配符索引来支持查询谓词的一部分,也不能使用通配符索引来支持另一部分。
  • MongoDB 不能使用多个通配符索引来支持同一查询中的不同谓词。
  • 当单个通配符索引可以支持多个查询字段的情况下,MongoDB只能使用通配符索引来支持其中一个查询字段。MongoDB 根据相关通配符索引路径自动选择支持通配符索引的字段。

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

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

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

笔记

$或行为

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

带排序的查询

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

  • 查询规划器选择通配符索引来满足查询谓词。
  • 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()

Copyright © 上海锦木信息技术有限公司 all right reserved,powered by Gitbook文件修订时间: 2023-09-01 17:10:26

results matching ""

    No results matching ""