Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MongoDB 部分索引(Partial Indexes)

MongoDB 部分索引(Partial Indexes)

作者头像
Leshami
发布于 2018-08-08 09:54:00
发布于 2018-08-08 09:54:00
1.8K00
代码可运行
举报
文章被收录于专栏:乐沙弥的世界乐沙弥的世界
运行总次数:0
代码可运行

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

一、语法描述

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    创建部分索引语法
    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、演示环境

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    > 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、创建部分索引

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//基于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
    }

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    部分索引只为集合中那些满足指定的筛选条件的文档创建索引。
    如果你指定的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 }) 

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    稀疏索引指的是在一个集合中文档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 唯一索引

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年12月27日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MongoDB 单键(列)索引
MongoDB支持基于集合文档上任意列创建索引。缺省情况下,所有的文档的_id列上都存在一个索引。基于业务的需要,可以基于一些重要的查询和操作来创建一些额外的索引。这些索引可以是单列,也可是多列(复合索引),多键索引,地理空间索引,文本索引以及哈希索引等。 本文主要描述在基于文档上的单列来创建索引。 一、创建语法 语法:db.collection.createIndex(keys, options) keys: 一个包含字段和值键值对的文档,指定该键即在该键上
Leshami
2018/08/13
1.1K0
MongoDB 单键(列)索引
MongoDB 复合索引
如下图所示,在集合的userid以及score列上创建一个复合索引,其中userid为升序,score为降序
Leshami
2018/08/13
3.2K0
MongoDB 复合索引
MongoDB 稀疏(间隙)索引(Sparse Indexes)
a、间隙索引就是创建索引的索引列在某些文档上列不存在,导致索引存在间隙。 b、间隙索引在创建时应指定选项:{ sparse: true } c、间隙索引列上可以指定唯一性约束
Leshami
2018/08/13
2.7K0
mongoDB 逻辑运算符
在mongoDB中,逻辑运算也是较为常用的运算,这些逻辑运算通常包含与或非,取反,存在等等。本文描述mongoDB几类常用的逻辑运算符同时给出演示示例,供大家参考。 一、mongoDB中的几种逻辑运算符 $or 逻辑或 $and 逻辑与 $not 逻辑非 $nor 逻辑or的取反 $exists 存在逻辑 $type 查询键的数据类型 二、演示逻辑运算 演示集合persons中用到的文档数据请参考:m
Leshami
2018/08/08
1.5K0
MongoDB执行计划获取(db.collection.explain())
在RDBMS中,无论那种数据库,都提供了SQL剖析工具,用来解决SQL效率低下的问题。在MongoDB中,也有相应的策略来实现剖析。MongoDB提供了db.collection.explain()方法, cursor.explain()方法,和explain命令去返回查询计划信息和查询计划的执行统计信息。这为我们诊断查询提供了极大的便利,本文主要描述db.collection.explain()的相关用法。 一、db.collection.explain()简介 支持下列操作返回查询计划
Leshami
2018/08/13
1.6K0
MongoDB执行计划获取(db.collection.explain())
MongoDB 唯一索引
MongoDB 单键(列)索引 MongoDB 复合索引 MongoDB 多键索引 MongoDB执行计划获取(db.collection.explain())
Leshami
2018/08/08
4K0
MongoDB 聚合索引
MongoDB 聚合索引是一种包含多个字段的索引,它可以提高查询效率,特别是在需要对多个字段进行查询或者聚合操作时。以下是 MongoDB 官方文档中关于聚合索引的详细说明和示例:
玖叁叁
2023/04/14
8550
MongoDB(六)—-MongoDB索引的额外属性
唯一索引会保证索引对应的键不会出现相同的值,比如_id索引就是唯一索引 创建索引时也需要保证属性中内容是不重复的 语法格式:
全栈程序员站长
2021/04/07
1K0
巧用MongoDB部分索引优化性能问题
最近研发提交业务需求,大概逻辑就是先统计总数,然后分页进行导出.SQL查询条件很简单。根据时间范围以及productTags字段必须存在作为条件.目前每天大约5000万数据量,数据保留6个月满足条件数据不多.但在没有索引的情况下,前端导出是卡死的.本次只讨论count性能问题,分页导数同样需要优化.具体SQL如下:
徐靖
2022/09/22
1.3K0
MongoDB 多键索引
更多参考 MongoDB 单键(列)索引 MongoDB 复合索引 MongoDB执行计划获取(db.collection.explain())
Leshami
2018/08/13
1.7K0
MongoDB 多键索引
【翻译】MongoDB指南/CRUD操作(四)
【原文地址】https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选择最有效的查询方案。然后每次执行查询时,查询系统使用此查询方案。 查询优化程序仅缓存可能有多种切实可行的方案的查询计划。 对于每一个查询,查询规划者在查询方案高速缓存中搜索适合查询形式的查询方案。如果没有匹配的查询方案,查询规划者生成几个备选方案并在一个实验周期内做出评估。查询规划者选择获胜的方案,创建包含获胜
甜橙很酸
2018/03/08
2K0
【翻译】MongoDB指南/CRUD操作(四)
MongoDB索引顺序导致慢SQL分析过程
最近监控MongoDB集群的慢日志,发现存在一个查询需要4s左右,返回结果集大部分情况下都为0(相当于SQL空跑),与研发沟通交流后,这个定时将检查已审核账单数据推送到ES中(双11时直接关闭这个功能,说明这个功能消耗资源)
徐靖
2022/08/23
8440
MongoDB索引顺序导致慢SQL分析过程
【Rochester】MongoDB的基本语法和使用
注:MongDB中默认的数据库为test,如果你没有选择数据库,集合将默认存放在test数据库中
Rochester
2021/06/23
2.8K0
MongoDB入门实战教程(9)
前面我们学习了如何套用常见的设计模式打造合适的模型设计,本篇我们来看看在MongoDB中如何使用索引来提高查询效率。
Edison Zhou
2021/07/01
1.7K0
快速体验mongoDB分片
1、mongodb分片的实质是将数据分散到不同的物理机器,以分散IO,提供并发与吞吐量 2、mongodb分片依赖于片键,即任意一个需要开启的集合都需要创建索引 3、开启分片的集合需要首先在DB级别启用库级分片 4、mongodb的分片由分片服务器,配置服务器以及路由服务器组成 5、基于分片可以结合副本集(replicate set)来实现高可用
Leshami
2018/08/13
1K0
云上MongoDB常见索引问题及最优索引规则大全
本文干货较多,建议收藏学习。先将文章结构速览奉上: 一、背景 二、MongoDB执行计划 2.1 queryPlanner信息 2.2 executionStats信息 2.3 allPlansExecution信息 三、云上用户建索引常见问题及优化方法 3.1 等值类查询常见问题及优化方法     3.1.1 同一类查询创建多个索引问题     3.1.2 多字段等值查询组合索引顺序非最优     3.1.3 最左原则包含关系引起的重复索引     3.1.4 唯一字段和其他字段组合引起的无用重复索引
腾讯云数据库 TencentDB
2022/04/07
2.4K0
云上MongoDB常见索引问题及最优索引规则大全
MongoDB操作&&注入漏洞&&未授权访问漏洞
注入不止有传统的SQL数据库,NoSQL型数据库也一样存在注入漏洞,在比赛中跟传统的注入相比也算新题型,不少同学可能还不太了解,本文向大家科普MongoDB数据库的常见操作以及攻击的方法——NoSQL注入和未授权访问
安恒网络空间安全讲武堂
2019/09/29
4.7K0
数据库MongoDB-索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对系统的性能是非常致命的。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
cwl_java
2021/02/04
6.2K0
mongoDB CRUD特性介绍
1、本文简要描述了mongoDB的CRUD的常规操作,并给出了示例演示 2、CRUD基本上等同于SQL数据库的增删改查 3、每一个操作都有更详细以及更丰富的用法,具体可参考官方文档
Leshami
2018/08/13
5260
mongoDB 比较运算符
比较运算符是我们学习任何语言或系统中最为常见的运算符之一。mongoDB的比较运算符,跟Linux的差不多,只不过每一个比较运算符前面会带有符号,他们分别是$eq、$gt、$gte、$lt、$lte、$ne、$in、符号,他们分别是\$eq、\$gt、\$gte、\$lt、\$lte、\$ne、\$in、nin等,下面将对这几个运算符进行描述。 一、比较运算符 $eq = "=" $gt (greater than ) > $gte
Leshami
2018/08/13
1.2K0
相关推荐
MongoDB 单键(列)索引
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验