每篇半小时1天入门MongoDB——4.MongoDB索引介绍及数据库命令操作

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

准备工作

继续连接到mongo

C:\Users\zouqi>mongo
MongoDB shell version: 3.0.7
connecting to: test

查看数据库和集合

复制代码
> show dbs
demo        0.078GB
local       0.078GB
myDatabase  0.078GB
myTest      0.078GB
> use myTest
switched to db myTest
> show collections
persons
system.indexes
复制代码

创建简单索引

数据准备,在CMD命令窗口中输入如下初始化脚本:

for(var i=0;i<200000;i++){db.books.insert({number:i,name:"book"+i})}

1、先检查一下查询性能

执行如下脚本:
var start=new Date()
db.books.find({number:20540})
var end=new Date()
end - start

复制代码
> db.books.find({number:20540})
{ "_id" : ObjectId("5953c63a797216100b773acb"), "number" : 20540, "name" : "book20540" }
> var start=new Date()
> db.books.find({number:20540})
{ "_id" : ObjectId("5953c63a797216100b773acb"), "number" : 20540, "name" : "book20540" }
> var end=new Date()
> end - start
110
复制代码

2、为number创建索引

(1代表升序,-1代表降序),在创建索引的时候,由于数据量比较大,会比较耗时,我们会看到执行创建索引脚本的时候,光标会有一定的延时。

复制代码
> db.books.ensureIndex({number:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
>
复制代码

3、再执行第一步的代码可以看出有数量级的性能提升

复制代码
> var start=new Date()
> db.books.find({number:20540})
{ "_id" : ObjectId("5953c63a797216100b773acb"), "number" : 20540, "name" : "book20540" }
> var end=new Date()
> end - start
15
>
复制代码

之前耗时是110毫秒,创建索引号耗时是15毫秒。

索引使用需要注意的地方

  1. 创建索引的时候要注意后面参数:1是正序 -1是倒序
  2. 索引的创建在提高查询性能的同时会影响插入的性能,对于经常查询少超入的文档可以考虑用索引。
  3. 组合索引要注意索引的先后顺序
  4. 每个键都创建索引不一定就能够提高性能
  5. 在做排序工作的时候,如果是超大数据量也是可以考虑加上索引用来提高排序的性能。

索引的名称可以用MongoVUE来查看


创建索引的同时我们还可以指定索引的名字
db.booksensureIndex({name:1},{name:"bookname")

4、唯一索引

如何解决文档books不能插入重复的数值?建立唯一索引

db.books.ensureIndex({name:-1},{unique:true})

测试:db.books.insert({name:"hello"})

运行结果如下:

复制代码
> db.books.insert({name:"hello"})
WriteResult({ "nInserted" : 1 })
> db.books.insert({name:"hello"})
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "E11000 duplicate key error index: myTest.books.$name_-1 dup key: { : \"hello\" }"
        }
})
>
复制代码

5、删除重复值

如果创建唯一索引之前已经存在重复数值该如何处理

db.books.ensureIndex({name:-1},{unique:true,dropDups:true})

6.Hint

如何强制查询使用指定的索引?

db.books.find({name:"hello",number:1}).hint({name:-1})

注意:指定索引必须是已经创建了的索引

7、Expain

如何详细查看本次查询使用哪个索引和查询数据的状态信息
db.books.find({name:"hello"}).explain()

复制代码
> db.books.find({name:"hello"}).explain()
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "myTest.books",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "name" : {
                                "$eq" : "hello"
                        }
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "name" : 1
                                },
                                "indexName" : "bookname",
                                "isMultiKey" : false,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "name" : [
                                                "[\"hello\", \"hello\"]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [
                        {
                                "stage" : "FETCH",
                                "inputStage" : {
                                        "stage" : "IXSCAN",
                                        "keyPattern" : {
                                                "name" : -1
                                        },
                                        "indexName" : "name_-1",
                                        "isMultiKey" : false,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                                "name" : [
                                                        "[\"hello\", \"hello\"]"
                                                ]
                                        }
                                }
                        }
                ]
        },
        "serverInfo" : {
                "host" : "DESKTOP-V7CFIC3",
                "port" : 27017,
                "version" : "3.0.7",
                "gitVersion" : "6ce7cbe8c6b899552dadd907604559806aa2e9bd"
        },
        "ok" : 1
}
复制代码

索引管理

1、system.indexes

在shell查看数据库中已经建立的索引
db.system.indexes.find()

复制代码
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.books" }
{ "v" : 1, "key" : { "number" : 1 }, "name" : "number_1", "ns" : "myTest.books" }
{ "v" : 1, "key" : { "name" : 1 }, "name" : "bookname", "ns" : "myTest.books" }
{ "v" : 1, "unique" : true, "key" : { "name" : -1 }, "name" : "name_-1", "ns" : "myTest.books" }
>
复制代码

db.system.namespaces.find()

复制代码
> db.system.namespaces.find()
{ "name" : "myTest.system.indexes" }
{ "name" : "myTest.persons" }
{ "name" : "myTest.persons.$_id_" }
{ "name" : "myTest.books" }
{ "name" : "myTest.books.$_id_" }
{ "name" : "myTest.books.$number_1" }
{ "name" : "myTest.books.$bookname" }
{ "name" : "myTest.books.$name_-1" }
>
复制代码

2、后台执行

执行创建索引的过程中会暂时锁表,此问题如何解决?
为了不影响查询,我们可以让索引的创建过程在后台执行 
db.books.ensureIndex({number:1},{background:true})

3、删除索引

批量和精确删除索引
db.runCommand({dropIndexes:"books",index:"name_-1"})

复制代码
> db.runCommand({dropIndexes:"books",index:"name_-1"})
{ "nIndexesWas" : 4, "ok" : 1 }
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.books" }
{ "v" : 1, "key" : { "number" : 1 }, "name" : "number_1", "ns" : "myTest.books" }
{ "v" : 1, "key" : { "name" : 1 }, "name" : "bookname", "ns" : "myTest.books" }
>
复制代码

db.runCommand({dropIndexes:"books",index:"*"})

复制代码
> db.runCommand({dropIndexes:"books",index:"*"})
{
        "nIndexesWas" : 3,
        "msg" : "non-_id indexes dropped for collection",
        "ok" : 1
}
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.books" }
>
复制代码

Count&Distinct&Group

1、Count

请查询persons中美国学生的人数
db.persons.find({country:"USA"}).count()

2、Distinct

请查询出persons中一共有多少个国家分别是什么
db.runCommand({distinct:"persons",key:"country"}).values

3、Group

语法:
db.runCommand({group:{
ns:集合名称,
Key:分组的键对象,
Initial:初始化累加器,
$reduce:组分解器,
Condition:条件,
Finalize:组玩传奇
}})
分组首先会按照key进行分组,每组的每一个文档都要执行$reduce的方法,它接收2个参数,一个是组内本条记录,一个是累加器数据。
请查出persons中每隔国家学生数学成绩最好的学生信息(必须在90分以上)

复制代码
db.runCommand({group:{
ns:"persons",
key:{"country":true},
initial:{m:0},
$reduce:function(doc,prev){
if(doc.m>prev.m){
prev.m=doc.m;
prev.name=doc.name;
prev.country=doc.country;
}
},
condition:{m:{$gt:90}}
}})
复制代码

在上面实例的基础之上把每个人的信息连接起来写一个描述赋值到m上
finalize:function(prev){
prev.m=prev.name+"Math scores"+prev.m
}

数据库命令操作

1、用命令执行一次删除表操作

db.runCommand({drop:"map"})

2、如何查询mongoDB为我们提供额命令

db.listCommands()

3、常用命令举例
查询服务器版本号和主机操作系统

db.runCommand({buildInfo:1})

查询执行集合的详细信息,大小、空间、索引等

db.runCommand({collStats:"persons"})

查看操作本集合最后一次错误信息

db.runCommand({getLastError:"persons"})

 本文转自邹琼俊博客园博客,原文链接:http://www.cnblogs.com/jiekzou/p/7092158.html,如需转载请自行联系原作者

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
6天前
|
存储 数据处理 数据库
深入了解达梦数据库的增删查改操作:从入门到精通
深入了解达梦数据库的增删查改操作:从入门到精通
|
1天前
|
存储 NoSQL 关系型数据库
Percona XtraBackup是否支持MongoDB数据库备份?
【5月更文挑战第13天】Percona XtraBackup是否支持MongoDB数据库备份?
10 1
|
4天前
|
存储 NoSQL MongoDB
Mongodb 入门
Mongodb 入门
8 0
|
4天前
|
SQL Java 关系型数据库
零基础轻松入门Java数据库连接(JDBC)
零基础轻松入门Java数据库连接(JDBC)
9 0
|
4天前
|
NoSQL 测试技术 定位技术
【MongoDB 专栏】MongoDB 的地理空间索引与位置查询
【5月更文挑战第10天】MongoDB 支持地理空间数据处理,提供2dsphere(球面)和2d(平面)索引,适用于地图导航、物流、社交网络等领域。通过创建索引,可加速位置查询,如查询范围、最近邻及地理空间聚合。案例包括地图应用、物流追踪和社交网络。注意数据准确性、索引优化和性能测试,以发挥其在地理空间处理中的潜力。学习此功能,为应用开发解锁更多可能性!
【MongoDB 专栏】MongoDB 的地理空间索引与位置查询
|
4天前
|
存储 NoSQL MongoDB
【MongoDB 专栏】如何高效使用 MongoDB 的索引
【5月更文挑战第10天】MongoDB的索引是提升查询性能的关键,它基于B树结构,分为单字段、复合、多键和文本索引。创建索引可通过`createIndex()`或管理工具,适用于频繁查询、排序分组和连接操作。优化策略包括选择合适字段、避免过度索引和定期评估。注意索引影响写入性能、大小限制及可能的失效情况。通过案例分析,应根据业务需求合理创建和使用索引,以实现最佳性能。
【MongoDB 专栏】如何高效使用 MongoDB 的索引
|
4天前
|
存储 NoSQL 关系型数据库
【MongoDB 专栏】MongoDB 与传统关系型数据库的比较
【5月更文挑战第10天】本文对比了MongoDB与传统关系型数据库在数据模型、存储结构、扩展性、性能、事务支持、数据一致性和适用场景等方面的差异。MongoDB以其灵活的文档模型、优秀的扩展性和高性能在处理非结构化数据和高并发场景中脱颖而出,而关系型数据库则在事务处理和强一致性上更具优势。两者各有适用场景,选择应根据实际需求来定。随着技术发展,两者正相互融合,共同构建更丰富的数据库生态。
【MongoDB 专栏】MongoDB 与传统关系型数据库的比较
|
4天前
|
存储 NoSQL MongoDB
【MongoDB 专栏】MongoDB 入门指南:从零开始学习
【5月更文挑战第10天】本文介绍了MongoDB,一个流行的NoSQL数据库,以其灵活的数据模型和高性能著称。内容包括MongoDB的基础知识、安装配置、文档数据模型、数据库操作(如创建、查询、更新和删除)、索引创建、数据备份恢复及性能优化策略。此外,还探讨了MongoDB在社交网络、电子商务等领域的应用。对于初学者,本文提供了从零开始学习MongoDB的入门指导。
【MongoDB 专栏】MongoDB 入门指南:从零开始学习
|
6天前
|
安全 Java 数据库连接
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
|
6天前
|
存储 Oracle 关系型数据库
达梦数据库入门语法:从基础到进阶的指南
达梦数据库入门语法:从基础到进阶的指南