MongoDB-索引的使用和索引类型

目录

    • 简介
    • 创建索引的方式
    • 索引的种类
      • 单列索引
      • 复合索引(多列索引)
      • 多键索引
      • 地理空间索引
      • 文本搜索索引
      • Hash索引
    • 索引属性

简介

  • MongoDB的索引种类还是不少的,因为它是个文档数据库,存储的数据种类杂七杂八的,针对MongoDB的索引大致可以分为,唯一索引、单列索引、多列索引(复合索引)、多键索引(数组字段索引)、文本搜索索引、地理空间索引,等。但其实非特殊业务,一般情况下使用到的索引也就单列索引和多列索引,以及唯一索引比较多。
  • MongoDB的索引使用B+Tree数据库结构,与MySQL的B+tree类似,如有兴趣可以在我另外一篇文章中查看B+tree的底层原理,这里就不再啰嗦了。
  • MongoDB在创建集合时,默认会对_id字段创建唯一索引,如果插入数据不指定_id字段,默认会随机生成一串字符作为_id列。

B+tree与B-Tree数据结构的不同处:链接: https://blog.csdn.net/h_3369/article/details/141357887?spm=1001.2014.3001.5502

创建索引的方式

  • MongoDB使用 db.collection.createIndex()语句进行创建索引。
  • 索引名称默认没有自定义的话,使用列名称加索引降序还是升序进行命名例如name_-1表示在name列上创建了一个降序的索引
  • 可以通过db.collection.getIndexes()查看某个集合上的索引情况。索引一旦创建后无法重命名,除非删除索引重新创建。
db.collection.createIndex( <key and index type specification>, <options> )
### 以下实例在name列创建一个降序索引,其中的-1表示降序,如果是1表示升序
db.collection.createIndex( { name: -1 } )
###对sid列创建一个升序索引,并自定义索引名为collection_sid_idx_1
db.zips.createIndex( { sid: 1 },{name:'collection_sid_idx_1'} )
###查询索引是否创建成功
db.collection.getIndexes()
###删除索引的方式
db.zips.dropIndex( "index_name" )

索引的种类

  • MongoDB索引的种类分为很多种,下面我们根据单个字段、多个字段、多键索引、地理空间索引、文本搜索索引、哈希索引、通配符索引这几个种类。进行介绍和使用。

单列索引

  • 顾名思义,就是我们集合中,某个列单独创建一个索引。基本上是对于这个列查询需求较高,重复值也不是太高的列,进行创建索引。其中每一个集合中,我们的_id字段就是单列索引,只是不同的是,他是个单列唯一索引。
  • MongoDB根据B-tree数据结构,在创建索引时,索引中可存储某个特定字段或多个字段的值,会对创建索引列的值进行排序,索引项的排序支持高效的等值匹配和基于范围的查询操作。此外,MongoDB 还可使用索引中的顺序来返回排序后的结果。

在这里插入图片描述

1.创建测试数据,使用MongoDB官方的测试数据。后面这个测试数据集合,还会用到,在另一给文档有详细的导入介绍,这里不再介绍导入方式了。

测试数据地址:https://media.mongodb.org/zips.json
导入方式:https://blog.csdn.net/h_3369/article/details/141923194?spm=1001.2014.3001.5501

2.对pop列创建一个升序索引,自定义名称为zips_pop_1

db.zips.createIndex( { pop: 1 },{name:'zips_pop_1'} )
###查询创建是否成功
db.zips.getIndexes()
[{ v: 2, key: { _id: 1 }, name: '_id_' },{ v: 2, key: { pop: 1 }, name: 'zips_pop_1' }
]

3.对嵌入式字段创建索引,也就是字段中的字段。

###插入数据
db.schools.insertOne({"_id": ObjectId("570c04a4ad233577f97dc459"),"studentsEnrolled": 1034,"location": { state: "NY", city: "New York" }}
)
###为嵌入式字段state创建索引
db.zips.createIndex( { "location.state": 1 },{name:'schools_location_statte_1'} )
###查看索引
db.schools.getIndexes()
[{ v: 2, key: { _id: 1 }, name: '_id_' },{v: 2,key: { 'location.state': 1 },name: 'schools_location_statte_1'}
]

复合索引(多列索引)

  • 复合索引,也叫多列索引,也可以说是联合索引,和MySQL联合索引一样,是将>=2列以上的值合在一起做索引,一半用于多条件查询语句,或者是单个字段重复值过高。
  • MongoDB复合索引的限制最多为32个列。
  • 单列索引的排序不是很重要,因为就一个列,但是复合索引的排序就很重要了,直接关系到了查询的性能,根据B+tree的规则,多列索引排序方式为,按照第一个字段排序,如果第一个字段的值相同按照第二个字段排序。而MongoDB的排序方式又有略微不同,MongoDB分为降序-1和升序1进行排序,所以当复合索引排序时,首先按照userid进行升序排列,在遇到相同的userid时再根据score降序排列。所以当复合索引的第一个列相同时,第二个列的值就是相同有序的。否则第二个列就不是有序的如下图。

在这里插入图片描述
创建复合索引

db.zips.createIndex( { "city": 1, "pop": 1 } )
###查询索引类型
[{ v: 2, key: { _id: 1 }, name: '_id_' },{ v: 2, key: { city: 1, pop: 1 }, name: 'city_1_pop_1' }
]
  • 复合索引的查询前缀:上方支持使用find( { city: “xxx” } )或者find( { city: “xxxx”, pop: { $gt: xx } } ),也就是说MongoDB的索引依然需要遵循最左原则。

多键索引

  • 多建索引是在数组列上,为数组列中的值进行创建的。MongoDB会为每个数组中的唯一元素,创建索引,但是如果数组中有多个值相同,那么索引中也只会保留他们其中的一个元素。
  • 如果创建索引时,字段是数组类型,MongoDB会自动创建多键索引,无需额外指定多键索引的类型。
  • 多建索引包含、多键唯一索引、多键复合索引、以及多键单列索引。

创建单列多键索引

  • 多建单列索引语法
db.coll.createIndex( { <field>: < 1 or -1 > } )
  • 多键复合索引语法
db.coll.createIndex( { <field>: < 1 or -1 > , <field>: < 1 or -1 >} )
  • 多键唯一索引语法
db.coll.createIndex( { <field>: < 1 or -1 >},{ unique: true } )

请注意:创建多键复合索引时,不可以是两个数组字段。如a:[1,2,3],b:[1,2,3],a和b两个列都是数组,无法一起创建多键索引。

在这里插入图片描述

地理空间索引

  • 地理空间索引,用于加速地理空间数据的查询,MongoDB将我们的省份、城市、经纬等信息进行创建索引,例如通过省份范围查找城市、区域等,运用到实际生活中,就是通过地图查找附近5公里内的餐厅等信息。
  • MongoDB通过R-tree数据结构存储地理空间索引,R树是一种多维的索引结构,适合存储多个维度的数据。与B-tree最大的不同点,是R-tree的数据节点的每个数据,都包含多个指向不同的数据的指针。而B-tree只是指向左右两条数据的指针。根绝R-tree这种矩阵式指针的特性,是比较适合做地理空间索引的。
  • MongoDB的地理空间索引分为两种,2dsphere和2d
    • 2d主要用于处理二维平面上的点,适用于需要在二维平面上进行空间查询的场景。它不考虑地球的曲率,因此更适合用于平面地图或时间连续数据等不需要考虑地球曲率的场景。
    • ‌2dsphere,则考虑了地球的曲率,适用于地球表面类型的地图。它允许使用GeoJSON格式指定点、线和多边形,提供了更准确的距离处理,如计算两个城市之间的距离。2dsphere索引基于WGS84基准,将地球表面模拟成一个扁球体,因此在两极地区会比较扁。这种索引考虑了地球的形状,提供了比2d索引更准确的距离计算。
  • 语法介绍
db.collection.createIndex( { <location field> : "2dsphere" } )
db.collection.createIndex( { <location field> : "2d" } )

创建地理空间索引
1.插入一批测试数据

db.places.insertMany( [{name: "Central Park",location: { type: "Point", coordinates: [ -73.97, 40.77 ] },category: "Parks"},{name: "Sara D. Roosevelt Park",location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },category: "Parks"},{name: "Polo Grounds",location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },category: "Stadiums"}
] )

2.根据location创建一个2dsphere地理空间索引

db.places.createIndex( { location: "2dsphere" } )
Enterprise mongodb_test> db.places.getIndexes()
[{ v: 2, key: { _id: 1 }, name: '_id_' },{v: 2,key: { location: '2dsphere' },name: 'location_2dsphere','2dsphereIndexVersion': 3}
]

3.使用near操作符,返回指定地址,1km–5km范围内的数据。

db.places.find({location:{ $near:{$geometry: { type: "Point",  coordinates: [ -73.9667, 40.78 ] },$minDistance: 1000,$maxDistance: 5000}}}
)
  • 对location字段进行过滤,过滤使用到near操作符
  • near表示指定地理空间查询要按从最近到最远的顺序为其返回文档的点。$near 操作符可以指定一个 GeoJSON 点或旧版坐标点。
  • near中通过geometry,返回指定范围的数据,minDistance表示最小为1000米,maxDistance表示最大为5000米

4.根据一个地址的经纬,查询category为"Parks" 的值,从近到远的数据有哪些,并且输出距离

db.places.aggregate( [{$geoNear: {near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },spherical: true,query: { category: "Parks" },distanceField: "calcDistance"}}
] )
...
[{_id: ObjectId('66ea72311106849c315e739c'),name: 'Central Park',location: { type: 'Point', coordinates: [ -73.97, 40.77 ] },category: 'Parks',calcDistance: 1147.4220523120937},{_id: ObjectId('66ea72311106849c315e739d'),name: 'Sara D. Roosevelt Park',location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },category: 'Parks',calcDistance: 7106.506152782792}
]
  • geoNear按距离指定点最近到最远的顺序输出文档。
  • near指定一个位置信息
  • spherical为true表示MongoDB 使用 $nearSphere 语义,并使用球面几何计算距离。为flase表示MongoDB 使用 $near 语义:2dsphere 索引用于球面,2d 索引用于平面。
  • query过滤条件为category字段为Parks的数据
  • distanceField表示,指定包含计算出的距离的字段。

文本搜索索引

  • 文本搜索索引(text),顾名思义,就是类似ES数据库的文本搜索,也可以进行分词搜索。
  • 一个集合上面只能存在一个文本索引( MongoDB Atlas 可以多个)
  • 文本搜索索引,通过$text操作符进行查询搜索数据,但是通配符索引不支持使用text操作符,虽然通配符文本索引和通配符索引共享通配符$**字段模式,但它们是不同的索引类型。 只有通配符文本索引支持$text操作符
  • 语法介绍
###创建索引
db.collection.createIndex( { <field1> : "text" ,  <field2> : "text" } )
###搜索数据
{$text: {$search: <string>,$language: <string>,$caseSensitive: <boolean>,$diacriticSensitive: <boolean>}
}
###在多个字段创建文本索引,使用通配符创建
db.collection.createIndex( {  "$**": "text" } )

Hash索引

  • hash索引只支持等值查询,不支持范围查询。并且不能增加唯一性的限制。
  • 可以在同一个列上,额外创建一个非hash索引,这样MongoDB对于范围查询时自动选择非hash索引了。
  • 一般情况在使用MongoDB分片的时候,可以使用到Hash索引。
  • 语法介绍
db.collection.createIndex( { _id: "hashed" } )
###复合hash索引
db.collection.createIndex( { "fieldA" : 1, "fieldB" : "hashed", "fieldC" : -1 } )

索引属性

  • 上面介绍完了索引的种类,索引还分为几种属性,分别是唯一索引、部分索引、稀疏索引、TTL索引、以及隐藏索引(4.4版本以后)
索引属性索引属性介绍属性关键字属性的值
唯一索引唯一索引顾名思义,当对唯一索引字段插入重复数据时,会被MongoDB所拒绝,MongoDB唯一索引也是可以存在null值得,在插入数据时唯一索引字段为空,唯一索引字段会为这行文档增加一个null值,但是整个集合也就允许这一个null值,下次再遇到null值就不符合唯一索引得约束,所以会被MongoDB拒绝unique默认值:false,可选值:true
部分索引部分索引,仅对集合中符合指定过滤条件得文档,进行创建索引,因此部分索引得存储要求更低,索引创建和维护得成本也就更低。partialFilterExpression指定语句得过滤条件:如:db.restaurants.createIndex( { cuisine: 1, name: 1 }, { partialFilterExpression: { rating: { $gt: 5 } } })
稀疏索引稀疏索引会跳过所有不包含索引键得文档,如果索引字段得值为空,那么会为他存储一个null值。sparse默认值:flase,可选择值:true
TTL索引TTL是一个特殊得索引属性,可以通过设置指定得过期时间,文档在达到过期事件后MongoDB,会自动删除这个文档。expireAfterSeconds[0-2147483647]秒,到达指定秒树后文档删除,0表示永远不过期
隐藏索引隐藏索引对查询规划期不可见,也无法使用这个索引,通过向规划期隐藏索引,用户可以评估在不删除索引的情况下,看出删除索引后的潜在影响,如果一旦需要这个索引,取消隐藏即可,无需重新创建。hidden,ratingshidden在创建索引时指定隐藏索引,值为true表示隐藏; ratings表示对已有索引进行隐藏, 使用语句db.restaurants.hideIndex( { borough: 1, ratings: 1 } )隐藏borough列这个索引

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148583.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL学习笔记(持续更新中)

1、Mysql概述 1.1 数据库相关概念 三个概念&#xff1a;数据库、数据库管理系统、SQL 名称全称简称数据库存储数据的仓库&#xff0c;数据是有组织的进行存储DataBase&#xff08;DB&#xff09;数据库管理系统操纵和管理数据库的大型软件DataBase Mangement System&#xf…

输电线塔目标检测数据集yolo格式该数据集包括2644张输电线塔高清图像,该数据集已经过yolo格式标注,具有完整的txt标注文件和yaml配置文件。

输电线塔目标检测数据集yolo格式 该数据集包括2644张输电线塔高清图像&#xff0c;该数据集已经过yolo格式标注&#xff0c;具有完整的txt标注文件和yaml配置文件。 输电线塔目标检测数据集 数据集名称 输电线塔目标检测数据集&#xff08;Transmission Tower Object Detecti…

网页设计html心得

一&#xff0c;认识网页 说到网页&#xff0c;其实大家并不陌生 1.1网页究竟是什么&#xff1f; 网页主要由文字、图像和超链接等元素构成。当然&#xff0c;除了这些元素&#xff0c;网页中还可以包含音频、视频以及Flash等。 1.2网页是如何形成的呢&#xff1f; 1.特殊的…

Spring Boot 中的拦截器 Interceptors

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 前言 Spring Boot中的拦截器&#xff08;Interceptor&#xff09;是一种用于拦截和处理HTTP请求的机制&#xff0c;它基于Spring MVC框架中的HandlerInterceptor接口实现。拦截器允许在请求到达控制器&#…

git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净,像刚clone下来一样

git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净&#xff0c;像刚clone下来一样 code review! 文章目录 git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净&#xff0c;像刚clone下来一样1.实现该功能的 Bash 脚本示例2.改进版&#xff1a;增加了gi…

微软宣布弃用面向企业的WSUS更新服务 仍然保留该服务但不再添加任何新功能

Windows Server Update Services 是微软面向企业推出的一项更新服务&#xff0c;该服务已经存在很多年&#xff0c;允许 IT 管理员控制内网设备的更新节奏。今年早些时候微软宣布将在 2025 年 4 月 18 日开始弃用 WSUS 驱动程序同步功能&#xff0c;因为大约只有 1/3 的 IT 管理…

大模型榜单汇总整理

大型语言模型&#xff08;LLM&#xff09;评估榜单提供了对不同模型性能的标准化比较&#xff0c;涵盖了从通用能力到特定领域应用的多个方面。这些榜单专注于评估模型在特定领域的应用能力&#xff0c;有助于开发者了解模型的优势和局限性&#xff0c;推动语言模型的发展和优化…

前端html+css+js 基础总结

​​​HTML 行级元素 标签分为行级元素与块级元素 行级元素占据区域由其显示内容决定&#xff0c;如span&#xff0c;img(图片)&#xff0c;<a></a>基本格式: <a href"链接" target"_blank"></a>用于跳转到其他网站&#xff0c…

镭射限高防外破预警装置-线路防外破可视化监控,安全尽在掌握中

镭射限高防外破预警装置-线路防外破可视化监控&#xff0c;安全尽在掌握中 在城市化浪潮的汹涌推进中&#xff0c;电力如同现代社会的生命之脉&#xff0c;其安全稳定运行直接关系到每一个人的生活质量和社会的整体发展。然而&#xff0c;随着建设的加速&#xff0c;电力设施通…

论文写作中的常见错误及规避策略

写论文&#xff0c;这个让无数学生闻风丧胆的挑战&#xff0c;可真是让人头大。 不管是初出茅庐的本科毕业论文&#xff0c;还是折腾得人头发都少了的硕士、博士论文&#xff0c;写作过程中的各种翻车场景简直就是论文写作的日常。 别慌&#xff0c;今天我就来当大家的论文救…

基于Python+SQLServer实现(界面)书店销售管理管理子系统

书店销售管理管理子系统 一、设 计 总 说 明 现在社会随着计算机技术迅速发展与技术的逐渐成熟&#xff0c;信息技术已经使人们的生活发生深刻的变化。生活中的各种服务系统也使人们在生活中的联系日常销售活动方式发生了很大的变化&#xff0c;让效率较低的手工操作成为过去…

vue3/Element-Plus/路由的使用

我们来实现一个简单的二级路由 1.准备主页和要配置的组件 主页面 <template><!-- 加载配置路由 --><RouterView></RouterView> </template><style scoped></style>组件1 <template><div>考试组件</div> </t…

【k8s】:DevOps 模式详解

1.什么是DevOps模式&#xff1f; DevOps 是当下非常火爆的一个概念&#xff0c;受到了很多互联网巨头的推崇。那么什么是 DevOps&#xff1f;它的全称是&#xff1a;集成开发与运维。至于它到底是干什么用的&#xff0c;为什么现在这么火爆&#xff0c;还得从源头说起。 1.1 …

vue3 vxe-grid 通过数据库返回的列信息,生成columns,并且其中有一列是img类型,进行slots的格式化处理。

1、一般我们写死的列信息的时候&#xff0c;会这样定义&#xff1a; 2、然后我们在template里面&#xff0c;这样这样写slots格式化部分&#xff1a; 这样表格中就会展示出一张图片&#xff0c;并且&#xff0c;我们点击了可以查看大图。 3、那么我们从数据库中返回的列&#…

二维矩阵的行、列、斜线特征(二维数组)

1. 行特征 二维 n*m 矩阵&#xff0c;用 x[i][j] 表示第 i 行第 j 列的元素。同一行的元素的 i 值是相同的。 例如&#xff0c;上图中绿色格子的数组元素分别是 x[4][1]&#xff0c;x[4][2]&#xff0c;x[4][3]&#xff0c;x[4][4]&#xff0c;x[4][5]&#xff0c;x[4][6]。 …

IDEA明明模块和环境变量配置的是JDK8但是显示别的版本解决方案

IDEA明明模块和环境变量配置的是JDK8但是显示别的版本解决方案 我目前系统中存在JDK8&#xff0c;JDK11,JDK17等多个版本&#xff0c;方便开发使用&#xff0c;但是有些时候也是比较烦人的&#xff0c;因为不同版本的JDK包有所区别。 需要注意的几个地方。方便自己排查一下。

UML——统一建模语言

序言&#xff1a; 是统一建模语言的简称&#xff0c;它是一种由一整套图表组成的标准化建模语言。UML用于帮助系统开发人员阐明&#xff0c;展示&#xff0c;构建和记录软件系统的产出。UML代表了一系列在大型而复杂系统建模中被证明是成功的做法&#xff0c;是开发面向对象软件…

信息安全工程师(14)网络攻击常见技术方法

前言 网络攻击的常见技术方法多种多样&#xff0c;这些方法旨在未经授权地访问、破坏或窃取目标系统的信息。 1. 侦察与信息收集 开放源情报收集&#xff1a;利用搜索引擎、社交媒体等公开渠道获取目标的基本信息。扫描技术&#xff1a;包括端口扫描、服务扫描等&#xff0c;以…

UE学习篇ContentExample解读-----------Blueprint_Mouse_Interaction

文章目录 总览描述&#xff08;Blueprint_Mouse_Interaction&#xff09;阅览解析1、PlayerControler分析2、拖拽球蓝图分析&#xff1a;3、移动的立方体分析&#xff1a; 新概念总结致谢&#xff1a; 总览描述&#xff08;Blueprint_Mouse_Interaction&#xff09; 打开关卡后…

腾讯云负载均衡ssl漏洞(CVE-201602183)解决

绿盟漏洞扫描腾讯云应用&#xff0c;提示有1个高危、1个中危。 看IP是应用服务器前端的负载均衡。 漏洞详细信息如下&#xff1a; 根据腾讯云文档&#xff0c;可以通过设置负载均衡加密算法设置&#xff0c;来缓解漏洞风险。 登录 负载均衡控制台&#xff0c;在左侧导航栏单击…