Mongodb索引中是否也应包含部分过滤器?

Mongodb索引中是否也应包含部分过滤器?,mongodb,mongodb-query,mongodb-indexes,Mongodb,Mongodb Query,Mongodb Indexes,我有这样一个问题: collection.find({ type: "person", image: { $exists: true } }, { sort: [ ["age", -1] ], limit: 9, ) 如果已经对字段进行了筛选,是否需要在索引中包含这些字段 collection.createIndex( {type: 1, image: 1, age: -1}, { partialFilterExpression: {

我有这样一个问题:

collection.find({
  type: "person",
  image: {
    $exists: true
  }
}, {
  sort: [
    ["age", -1]
  ],
  limit: 9,
)
如果已经对字段进行了筛选,是否需要在索引中包含这些字段

collection.createIndex(
  {type: 1, image: 1, age: -1}, 
  { 
    partialFilterExpression: {
      type: 'person',
      image: {
        $exists: true
      }
    },
    background: true
  }
)
或者它已经通过部分过滤表达式知道了,而我只是通过不固定的东西进行查询

collection.createIndex(
  {age: -1}, 
  { 
    partialFilterExpression: {
      type: 'person',
      image: {
        $exists: true
      }
    },
    background: true,
    name: "ageIndex"
  }
)
考虑一下,也许正确的做法是不索引所有字段,而是使用提示强制db使用索引

collection.find({
  type: "person",
  image: {
    $exists: true
  }
}, {
  sort: [
    ["age", -1]
  ],
  limit: 9,
).hint("ageIndex")
这是否会正确使用索引并忽略集合中的其他文档?

根据,如果字段已经在partialFilterExpression中,则无需在索引中包含这些字段(如果在此表达式中执行查询)

下面的索引对于所提供的查询非常有效

collection.createIndex(
  {age: -1}, 
  {partialFilterExpression: { type: 'person', image: { $exists: true }}}
)
查询:

collection.find({type: "person", image: { $exists: true }}, {sort: [["age", -1]])
db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )
甚至不需要提示

重要提示:如果类型不是“person”,或不提供图像过滤器,则索引将不起作用

只有当查询结果在索引中100%时,索引才会工作

文档中的另一个示例:

索引:

db.restaurants.createIndex(
   { cuisine: 1, name: 1 },
   { partialFilterExpression: { rating: { $gt: 5 } } }
)
查询:

collection.find({type: "person", image: { $exists: true }}, {sort: [["age", -1]])
db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )
此查询不属于上述索引,因为它包含低于5的评级。

考虑正在查询的样本文档集合,如问题所示:

{ _id: 1, type: "person", image: "i-1", age: 19, "fld": 12 },
{ _id: 2, type: "person", image: "i-2", age: 22, "fld": 121 },
{ _id: 3, type: "thing", image: "i-99", age: 29, "fld": 1212 },    // 'type' not 'person'
{ _id: 4, type: "person", age: 31, "fld": 12121 },                 // 'image' missing
{ _id: 5, type: "person", image: "i-3", age: 13, "fld": 121212 },
{ _id: 6, type: "person", age: 43, "fld": 1212121 },               // 'image' missing
{ _id: 7, type: "person", image: "i-4", age: 20, "fld": 1 }
如果已经有字段,是否需要在索引中包含它们 过滤?或者它已经通过部分过滤器表达式知道了吗 我只是在问什么是不固定的

collection.createIndex(
  {age: -1}, 
  { 
    partialFilterExpression: {
      type: 'person',
      image: {
        $exists: true
      }
    },
    background: true,
    name: "ageIndex"
  }
)
创建索引:

注意,索引字段仅针对类型和年龄。为什么?这将在下面的索引使用验证中解释

查询:

结果是:

查询将按排序顺序返回预期的筛选文档和

{ "_id" : 2, "type" : "person", "image" : "i-2", "age" : 22, "fld" : 121 }
{ "_id" : 7, "type" : "person", "image" : "i-4", "age" : 20, "fld" : 1 }
{ "_id" : 1, "type" : "person", "image" : "i-1", "age" : 19, "fld" : 12 }
{ "_id" : 5, "type" : "person", "image" : "i-3", "age" : 13, "fld" : 121212 }
索引使用验证:

可以通过使用explain方法生成查询计划来验证索引使用情况:

计划输出显示筛选和排序操作的索引使用情况。这被称为IXSCAN索引扫描,计划中没有排序阶段。这是此查询的索引的正确用法

在索引定义中,type+age两个字段指定了复合索引。这要求将索引应用于筛选的类型和排序的年龄。无法在索引定义中指定字段图像,因为它未与相等条件uses$exists一起使用;如果指定,则索引将不用于来自的以下排序字段:

索引可以支持对索引的非前缀子集进行排序操作 索引键模式。为此,查询必须包含相等项 排序键之前的所有前缀键上的条件

查询计划是其中的一部分:

{
    "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.persons",
            "indexFilterSet" : false,
            "parsedQuery" : {
                    "$and" : [
                            {
                                    "type" : {
                                            "$eq" : "person"
                                    }
                            },
                            {
                                    "image" : {
                                            "$exists" : true
                                    }
                            }
                    ]
            },
            "queryHash" : "25E877F5",
            "planCacheKey" : "C9D745BE",
            "winningPlan" : {
                    "stage" : "FETCH",
                    "filter" : {
                            "image" : {
                                    "$exists" : true
                            }
                    },
                    "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                    "type" : 1,
                                    "age" : -1
                            },
                            "indexName" : "type_1_age_-1",
                            "isMultiKey" : false,
                            "multiKeyPaths" : {
                                    "type" : [ ],
                                    "age" : [ ]
                            },
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : true,
                            "indexVersion" : 2,
                            "direction" : "forward",
                            "indexBounds" : {
                                    "type" : [
                                            "[\"person\", \"person\"]"
                                    ],
                                    "age" : [
                                            "[MaxKey, MinKey]"
                                    ]
                            }
                    }
            }, ...