MongoDB 部分索引(Partial Indexes)

简介: MongoDB部分索引只为那些在一个集合中,满足指定的筛选条件的文档创建索引。由于部分索引是一个集合文档的一个子集,因此部分索引具有较低的存储需求,并降低了索引创建和维护的性能成本。

MongoDB部分索引只为那些在一个集合中,满足指定的筛选条件的文档创建索引。由于部分索引是一个集合文档的一个子集,因此部分索引具有较低的存储需求,并降低了索引创建和维护的性能成本。部分索引通过指定过滤条件来创建,可以为MongoDB支持的所有索引类型使用部分索引。

一、语法描述

    创建部分索引语法
    db.collection.createIndex(keys, options)


    options可以使用partialFilterExpression,即部分过滤表达式,其类型为文档类型

    过滤表达式通常包括以下

            equality expressions (i.e. field: value or using the $eq operator),
            $exists: true expression,
            $gt, $gte, $lt, $lte expressions,
            $type expressions,
            $and operator at the top-level only

    过滤表达式使用示例:
        db.persons.createIndex({name:1},{partialFilterExpression:{age: {$gt:25}}})

二、演示部分索引

1、演示环境

    > db.version()
    3.2.10

    //演示中用到的文档,可参考:http://blog.csdn.net/leshami/article/details/52672310

    > db.persons.find().pretty().limit(1)
    {
            "_id" : ObjectId("5812cbaaa129eed14b46458d"),
            "name" : "robinson.cheng",
            "age" : 25,
            "email" : "robinson.cheng@qq.com",
            "score" : {
                    "c" : 89,   //Author : Leshami
                    "m" : 96,   //Blog   : http://blog.csdn.net/leshami
                    "e" : 87
            },
            "country" : "USA",
            "books" : [
                    "JS",
                    "C++",
                    "EXTJS",
                    "MONGODB"
            ]
    }

    > db.persons.find().count()
    11

2、创建部分索引

//基于age列创建大于25岁的部分索引
    > db.persons.createIndex({country:1},{partialFilterExpression: {age: {$gt:25}}})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }

    //查询谓词条件为{country:"China",age:{$gt:25},年龄大于25
    > db.persons.find({country:"China",age:{$gt:25}}).explain()
    {
            "queryPlanner" : {
                    ......
                    "winningPlan" : {
                            "stage" : "FETCH",
                            "filter" : {
                                    "age" : {
                                            "$gt" : 25
                                    }
                            },
                            "inputStage" : {
                                    "stage" : "IXSCAN",
                                    "keyPattern" : {
                                            "country" : 1
                                    },
                                    "indexName" : "country_1",
                                       .......
                                    "isPartial" : true,  //这里描述为部分索引
                                    "indexVersion" : 1,
                                    "direction" : "forward",
                                    "indexBounds" : {
                                            "country" : [
                                                    "[\"China\", \"China\"]"
                         ......
            "ok" : 1
    }

    //查询谓词条件为{country:"China",age:{$gte:25}},年龄大于等于25
    > db.persons.find({country:"China",age:{$gte:25}}).explain()
    {
            "queryPlanner" : {
                    ........
                    "winningPlan" : {
                            "stage" : "COLLSCAN", //此时为集合扫描方式
                            "filter" : {
                                    "$and" : [
                                            {
                                                    "country" : {
                                                            "$eq" : "China"
                                                    }
                                            },
                                            {
                                                    "age" : {
                                                            "$gte" : 25
              ......
            "ok" : 1
    }

    //查询谓词为{country:"China",age:{$gte:26}},年龄大于等于26
    > db.persons.find({country:"China",age:{$gte:26}}).explain()
    {
            "queryPlanner" : {
             ......
                    "winningPlan" : {
                            "stage" : "FETCH",
                            "filter" : {
                                    "age" : {
                                            "$gte" : 26
                                    }
                            },
                            "inputStage" : {
                                    "stage" : "IXSCAN",//此时为索引扫描,因为26大于索引值25
                                    "keyPattern" : {
                                            "country" : 1
                                    },
                                    "indexName" : "country_1",
                                     ......
                                    "isPartial" : true,
                                    "indexVersion" : 1,
                                    "direction" : "forward",
                                    "indexBounds" : {
                                            "country" : [
                                                    "[\"China\", \"China\"]"
             ......
            "ok" : 1
    }

    //谓词{country:"China",age:{$lt:25},年龄小于25
    > db.persons.find({country:"China",age:{$lt:25}}).explain()
    {
            "queryPlanner" : {
           .......
                    "winningPlan" : {
                            "stage" : "COLLSCAN", //小于25为集合扫描方式
                            "filter" : {
                                    "$and" : [
                                            {
                                                    "country" : {
                                                            "$eq" : "China"
                                                    }
                                            },
                                            {
                                                    "age" : {
                                                            "$lt" : 25
            ......
            "ok" : 1
    }

三、创建部分唯一索引的一些限制

    部分索引只为集合中那些满足指定的筛选条件的文档创建索引。
    如果你指定的partialfilterexpression和唯一约束、那么唯一性约束只适用于满足筛选条件的文档。
    具有唯一约束的部分索引不会阻止不符合唯一约束且不符合过滤条件的文档的插入。

    示例文档
    > db.users.insertMany([
    { "_id" : ObjectId("56424f1efa0358a27fa1f99a"), "username" : "david", "age" : 29 },
    { "_id" : ObjectId("56424f37fa0358a27fa1f99b"), "username" : "amanda", "age" : 35 },
    { "_id" : ObjectId("56424fe2fa0358a27fa1f99c"), "username" : "rajiv", "age" : 57 }])

    //为集合添加索引
    > db.users.createIndex(
        { username: 1 },
        { unique: true, partialFilterExpression: { age: { $gte: 21 } } }
     )

    //在集合users上插入用户名相同的文档,收到了重复键的错误提示
    > db.users.insert( { username: "david", age: 27 } )
    WriteResult({
            "nInserted" : 0,
            "writeError" : {
                    "code" : 11000,
                    "errmsg" : "E11000 duplicate key error collection: test.users index: username_1 dup key: { : \"david\" }"
            }
    })

    //下面插入年龄小于部分索引值或者age键为空的同用户名文档,可以成功插入。
    //也就是说对于不在部分索引限制之类的其他键值重复是允许的
    > db.users.insert( { username: "david", age: 20 } )
    WriteResult({ "nInserted" : 1 })
    > db.users.insert( { username: "amanda" } )
    WriteResult({ "nInserted" : 1 })
    > db.users.insert( { username: "rajiv", age: null } )
    WriteResult({ "nInserted" : 1 }) 

四、部分索引与稀疏索引的比对

    稀疏索引指的是在一个集合中文档A,C中包含某些列,如Key_A,而其他文档不包含Key_A,Key_A上的索引为稀疏索引
    部分索引代表的稀疏索引提供的功能的一个超集,应该优先于稀疏索引
    部分索引主要是针对那些满足条件的文档(非字段缺失)创建索引,比稀疏索引提供了更具有表现力
    稀疏索引是文档上某些字段的存在与否,存在则为其创建索引,否则该文档没有索引键

    如下示例,可以使用部分索引达到实现稀疏索引相同的效果(在名字列上过滤表达式为判断列是否存在)

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

    基于非索引列过滤的部分索引
    如下示例,过滤表达式为非索引列,及email列
    db.contacts.createIndex(
       { name: 1 },
       { partialFilterExpression: { email: { $exists: true } } }
    )       

    在这种情况下,索引要如何才能被使用到呢?
    查询谓词在email字段上应该包含一个非空的匹配,同时也要使用name作为过滤条件,如下:

    //下面的查询将使用索引
    db.contacts.find( { name: "xyz", email: { $regex: /\.org$/ } } )

    //下面的查询将不会使用到索引
    db.contacts.find( { name: "xyz", email: { $exists: false } } )     

五、小结

a、部分索引就是带有过滤条件的索引,即索引只存在与某些文档之上
b、满足过滤条件的文档在查询时,其执行计划将使用该列上的索引,否则不会被使用
c、稀疏索引与部分索引的差异是一个是基于某些文档存在的列,一个是列上的某些匹配条件的值
d、可以基于某个列上创建索引,而在另外的列来使用过滤条件

六、更多参考
MongoDB 单键(列)索引
MongoDB 复合索引
MongoDB 多键索引
MongoDB执行计划获取(db.collection.explain())
MongoDB 唯一索引

DBA牛鹏社(SQL/NOSQL/LINUX)

目录
相关文章
|
存储 NoSQL MongoDB
微服务——MongoDB常用命令——MongoDB索引知识概述
本文介绍MongoDB索引相关知识,包括其在查询中的重要作用。索引可避免全集合扫描,显著提升查询效率,尤其在处理海量数据时。通过B树数据结构存储字段值并排序,支持相等匹配、范围查询及排序操作。文中还提供了官方文档链接以供深入学习。
280 0
|
存储 NoSQL MongoDB
掌握MongoDB索引优化策略:提升查询效率的关键
在数据库性能调优中,索引是提升查询效率的利器。本文将带你深入了解MongoDB索引的内部工作原理,探讨索引对查询性能的影响,并通过实际案例指导如何针对不同的查询模式建立有效的索引。不仅将涵盖单一字段索引,还会探讨复合索引的使用,以及如何通过分析查询模式和执行计划来优化索引,最终实现查询性能的最大化。
|
存储 NoSQL MongoDB
微服务——MongoDB常用命令——MongoDB索引的类型
本节介绍了MongoDB中索引的几种类型及其特点。包括单字段索引,支持升序/降序排序,索引顺序对操作无影响;复合索引,字段顺序重要,可实现多级排序;地理空间索引,支持平面与球面几何查询;文本索引,用于字符串搜索并存储词根;哈希索引,基于字段值散列,适合等值匹配但不支持范围查询。
384 1
微服务——MongoDB常用命令——MongoDB索引的类型
|
存储 NoSQL 定位技术
MongoDB索引知识
MongoDB索引是提升查询性能的关键工具,通过构建特殊的数据结构(如B树)优化数据访问路径。无索引时,查询需全集合扫描,时间复杂度为O(n);使用索引后可降至O(log n),实现毫秒级响应。MongoDB支持多种索引类型:单字段索引适用于高频单字段查询;复合索引基于最左前缀原则优化多条件过滤和排序;专业索引包括地理空间索引(支持LBS服务)、文本索引(全文搜索)和哈希索引(分片键优化)。合理选择和优化索引类型,可显著提升数据库性能。建议使用explain()分析查询计划,并定期清理冗余索引。
|
存储 NoSQL 关系型数据库
MongoDB索引知识
MongoDB索引知识
200 1
MongoDB索引知识
|
存储 NoSQL MongoDB
MongoDB 索引限制
10月更文挑战第22天
348 2
|
NoSQL MongoDB 索引
MongoDB 高级索引
10月更文挑战第22天
198 2
|
存储 NoSQL MongoDB
MongoDB 索引
MongoDB 索引
233 3
|
NoSQL MongoDB 索引
MongoDB 覆盖索引查询
10月更文挑战第21天
218 1
|
存储 NoSQL 关系型数据库
MongoDB中的索引操作总结
这篇文章总结了MongoDB中索引的概念、创建方法、常见操作指令、限制以及索引对查询效率的影响。
1093 3

推荐镜像

更多