Mongodb-基本操作

数据库操作

创建

  • 选择和创建数据库的语法格式:
    如果数据库不存在则自动创建,例如,以下语句创建 spitdb 数据库:
use spitdb

查看

  • 查看当前正在使用的数据库命令
show dbs
或
show databases

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mydb    0.000GB
  • 查看有权限查看的所有的数据库命令
db

> db
test

MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。

注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

另外:
数据库名可以是满足以下条件的任意UTF-8字符串。

  • 不能是空字符串("")。
  • 不得含有’ '(空格)、.、$、/、\和\0 (空字符)。
  • 应全部小写。
  • 最多64字节。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,该用户自动继承所有数据库的权限。
一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

删除

  • 数据库的删除
    MongoDB 删除数据库的语法格式如下:
db.dropDatabase()

db.dropDatabase()
{ ok: 1, dropped: 'mydb' }

集合操作

集合创建

  • 集合的隐式创建
    当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
  • 集合的显式创建(了解)
基本语法格式:
db.createCollection(name)
name: 要创建的集合名称
 集合的命名规范:
- 集合名不能是空字符串""。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以"system."开头,这是为系统集合保留的前缀。
- 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。

删除集合

集合删除语法格式如下:

db.collection.drop()
或
db.集合.drop()

db.comment.drop()
true

如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。

文档(document)的操作

文档(document)的数据结构和 JSON 基本一样,所有存储在集合中的数据都是 BSON 格式。

插入

  • 单条文档插入
db.collection.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
}
)
ParameterTypeDescription
documentdocument or array要插入到集合中的文档或文档数组。((json格式)
writeConcerndocumentOptional. A document expressing the write concern. Omit to use the default write concern.See Write Concern.Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern.
orderedboolean可选。如果为真,则按顺序插入数组中的文档,如果其中一个文档出现错误,MongoDB将返回而不处理数组中的其余文档。如果为假,则执行无序插入,如果其中一个文档出现错误,则继续处理数组中的主文档。在版本2.6+中默认为true
db.comment.insert({"_id":"0","articleid":"100000","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Rose","createdatetime":new Date(),"likenum":NumberInt(10),"state":null})
{ acknowledged: true, insertedIds: { '0': '0' } }

1)comment集合如果不存在,则会隐式创建
2)mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。
3)插入当前日期使用 new Date()
4)插入的数据如果没有指定 _id ,会自动生成主键值
5)如果某字段没值,可以赋值为null,或不写该字段。

注意:

  1. 文档中的键/值对是有序的。
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

文档键命名规范:
键不能含有\0 (空字符)。这个字符用来表示键的结尾。
.和$有特别的意义,只有在特定环境下才能使用。
以下划线"_"开头的键是保留的(不是严格要求的)。

  • 多条文档插入
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
db.comment.insertMany([{"_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},{"_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},{"_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},{"_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},{"_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}]);
{ acknowledged: true,
  insertedIds: { '0': '1', '1': '2', '2': '3', '3': '4', '4': '5' } }

1)插入时指定了 _id ,则主键就是该值。
2)如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
3)因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。

查询

查询数据的语法格式如下:

db.collection.find(<query>, [projection])
ParameterTypeDescription
querydocument可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档( {} )
projectiondocument可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,请省略此参数。
  • 查询所有

    db.comment.find() #或find({})
    { _id: '0',
      articleid: '100000',
      content: '今天天气真好,阳光明媚',
      userid: '1001',
      nickname: 'Rose',
      createdatetime: 2022-01-21T12:57:49.081Z,
      likenum: 10,
      state: null }
    { _id: '1',
      articleid: '100001',
      content: '我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。',
      userid: '1002',
      nickname: '相忘于江湖',
      createdatetime: 2019-08-05T22:08:15.522Z,
      likenum: 1000,
      state: '1' }
    { _id: '2',
      articleid: '100001',
      content: '我夏天空腹喝凉开水,冬天喝温开水',
      userid: '1005',
      nickname: '伊人憔悴',
      createdatetime: 2019-08-05T23:58:51.485Z,
      likenum: 888,
      state: '1' }
    { _id: '3',
      articleid: '100001',
    ......
    
  • 查询某些

db.comment.find({},{content:1,nikename:1}) #注意:1
{ _id: '0', content: '今天天气真好,阳光明媚' }
{ _id: '1', content: '我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。' }
{ _id: '2', content: '我夏天空腹喝凉开水,冬天喝温开水' }
{ _id: '3', content: '我一直喝凉开水,冬天夏天都喝。' }
{ _id: '4', content: '专家说不能空腹吃饭,影响健康。' }
{ _id: '5', content: '研究表明,刚烧开的水千万不能喝,因为烫嘴。' }
  • 条件查询
db.comment.find({userid:'1004'},{content:1,nikename:1})
{ _id: '3', content: '我一直喝凉开水,冬天夏天都喝。' }
  • 去除索引
db.comment.find({},{content:1,nikename:1,_id:0}) **#_id:0**
{ content: '今天天气真好,阳光明媚' }
{ content: '我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。' }
{ content: '我夏天空腹喝凉开水,冬天喝温开水' }
{ content: '我一直喝凉开水,冬天夏天都喝。' }
{ content: '专家说不能空腹吃饭,影响健康。' }
{ content: '研究表明,刚烧开的水千万不能喝,因为烫嘴。' }
#记录名写错,系统不会提醒报错,如上面,nickname写成了nikename
  • 统计查询
db.collection.count(query, options)
db.comment.find().count()
6
db.comment.countDocuments({userid:'1003'})
2
  • 分页列表查询

使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据

db.comment.find({},{userid:1,nicknam:1,likenum:1}).limit(2)
{ _id: '0', userid: '1001', likenum: 10 }
{ _id: '1', userid: '1002', likenum: 1000 }
db.comment.find({},{userid:1,nicknam:1,likenum:1}).limit(2).skip(2)
{ _id: '2', userid: '1005', likenum: 888 }
{ _id: '3', userid: '1004', likenum: 666 }
  • 排序
db.COLLECTION_NAME.find().sort({KEY:1})
或
db.集合名称.find().sort(排序方式)
> db.comment.find({},{userid:1,nickname:1}).sort({nickname:1})
{ "_id" : "0", "userid" : "1001", "nickname" : "Rose" }
{ "_id" : "2", "userid" : "1005", "nickname" : "伊人憔悴" }
{ "_id" : "4", "userid" : "1003", "nickname" : "凯撒" }
{ "_id" : "5", "userid" : "1003", "nickname" : "凯撒" }
{ "_id" : "3", "userid" : "1004", "nickname" : "杰克船长" }
{ "_id" : "1", "userid" : "1002", "nickname" : "相忘于江湖" }

复杂条件查询

  • 正则表达式

MongoDB的模糊查询是通过正则表达式的方式实现的。格式为:

db.collection.find({field:/正则表达式/})
或
db.集合.find({字段:/正则表达式/})

包含:/…/

db.comment.find({content:/开水/})
{ _id: '2',
  articleid: '100001',
  content: '我夏天空腹喝凉开水,冬天喝温开水',
  userid: '1005',
  nickname: '伊人憔悴',
  createdatetime: 2019-08-05T23:58:51.485Z,
  likenum: 888,
  state: '1' }
{ _id: '3',
  articleid: '100001',
  content: '我一直喝凉开水,冬天夏天都喝。',
  userid: '1004',
  nickname: '杰克船长',
  createdatetime: 2019-08-06T01:05:06.321Z,
  likenum: 666,
  state: '1' }

^开头

db.comment.find({content:/^我/})
{ _id: '1',
  articleid: '100001',
  content: '我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。',
  userid: '1002',
  nickname: '相忘于江湖',
  createdatetime: 2019-08-05T22:08:15.522Z,
  likenum: 1000,
  state: '1' }
{ _id: '2',
  articleid: '100001',
  content: '我夏天空腹喝凉开水,冬天喝温开水',
  userid: '1005',
  nickname: '伊人憔悴',
  createdatetime: 2019-08-05T23:58:51.485Z,
  likenum: 888,
  state: '1' }
{ _id: '3',
  articleid: '100001',
  content: '我一直喝凉开水,冬天夏天都喝。',
  userid: '1004',
  nickname: '杰克船长',
  createdatetime: 2019-08-06T01:05:06.321Z,
  likenum: 666,
  state: '1' }

db.comment.find({content:/开水/},{userid:1,nickname:1})
{ _id: '2', userid: '1005', nickname: '伊人憔悴' }
{ _id: '3', userid: '1004', nickname: '杰克船长' }
  • 包含查询
    包含使用$in操作符。
db.comment.find({userid:{$in:['1003','1004']}})
{ _id: '3',
  articleid: '100001',
  content: '我一直喝凉开水,冬天夏天都喝。',
  userid: '1004',
  nickname: '杰克船长',
  createdatetime: 2019-08-06T01:05:06.321Z,
  likenum: 666,
  state: '1' }
{ _id: '4',
  articleid: '100001',
  content: '专家说不能空腹吃饭,影响健康。',
  userid: '1003',
  nickname: '凯撒',
  createdatetime: 2019-08-06T08:18:35.288Z,
  likenum: 2000,
  state: '1' }
{ _id: '5',
  articleid: '100001',
  content: '研究表明,刚烧开的水千万不能喝,因为烫嘴。',
  userid: '1003',
  nickname: '凯撒',
  createdatetime: 2019-08-06T11:01:02.521Z,
  likenum: 3000,
  state: '1' }

db.comment.find({userid:{$in:['1003','1004']}},{userid:1,nickname:1})
{ _id: '3', userid: '1004', nickname: '杰克船长' }
{ _id: '4', userid: '1003', nickname: '凯撒' }
{ _id: '5', userid: '1003', nickname: '凯撒' }
  • 条件连接查询

a n d , and, and,or

db.comment.find({$and:[{content:/开水/},{userid:'1004'}]},{userid:1,nickname:1,content:1})
{ _id: '3',
  content: '我一直喝凉开水,冬天夏天都喝。',
  userid: '1004',
  nickname: '杰克船长' }

更新

语法

db.collection.update(query, update, options)
//或
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)
ParameterTypeDescription
querydocument更新的选择条件。可以使用与find()方法中相同的查询选择器,类似sql update查询内where后面的。。在3.0版中进行了更改:当使用upsert:true执行update()时,如果查询使用点表示法在_id字段上指定条件,则MongoDB将拒绝插入新文档。
updatedocument or pipeline要应用的修改。该值可以是:包含更新运算符表达式的文档,或仅包含:对的替换文档,或在MongoDB 4.2中启动聚合管道。管道可以由以下阶段组成:
upsertboolean可选。如果设置为true,则在没有与查询条件匹配的文档时创建新文档。默认值为false,如果找不到匹配项,则不会插入新文档。
multiboolean可选。如果设置为true,则更新符合查询条件的多个文档。如果设置为false,则更新一个文档。默认值为false。
writeConcerndocument可选。表示写问题的文档。抛出异常的级别。
collationdocument可选。指定要用于操作的校对规则。校对规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音标记的规则。校对规则选项具有以下语法:

校对规则:
{区域设置:,caseLevel:,caseFirst:,强度:,numericordering:,替代:,最大变量:,向后:}
指定校对规则时,区域设置字段是必需的;所有其他校对规则字段都是可选的。有关字段的说明,请参阅校对规则文档。如果未指定校对规则,但集合具有默认校对规则(请参见db.createCollection()),则该操作将使用为集合指定的校对规则。
如果没有为集合或操作指定校对规则,MongoDB将使用本中使用的简单二进制比较进行字符串比较。不能为一个操作指定多个校对规则。例如,不能为每个字段指定不同的校对规则,或者如果使用排序执行查找,则不能将一个校对规则用于查找,另一个校对规则用于排序。3.4版新增。 |
| arrayFilters | array | 可选。一个筛选文档数组,用于确定要为数组字段上的更新操作修改哪些数组元素。 |
| hint | Document or string | 可选。指定用于支持查询谓词的索引的文档或字符串。该选项可以采用索引规范文档或索引名称字符串。如果指定的索引不存在,则说明操作错误。例如,请参阅版本4中的“为更新操作指定提示。 |

  • 覆盖

Mongodb Compass 5会对此报错

db.comment.update({_id:"1"},{likenum:NumberInt(1001)})

db.comment.update({_id:"1"},{likenum:NumberInt(1001)})
MongoInvalidArgumentError: Update document requires atomic operators
......

atomic operators:

$set
用来指定一个键并更新键值,若键不存在并创建。
{ $set : { field : value } }
$unset
用来删除一个键。
{ $unset : { field : 1} }
$inc
$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
{ $inc : { field : value } }
$push
{ $push : { field : value } }
把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。

换到shell环境:

> db.comment.update({likenum:888},{userid:'1009'})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.comment.find()
{ "_id" : "1", "articleid" : "100001", "content" : "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。", "userid" : "1002", "nickname" : "相忘于江湖", "createdatetime" : ISODate("2019-08-05T22:08:15.522Z"), "likenum" : 1000, "state" : "1" }
{ "_id" : "2", "userid" : "1009" }
{ "_id" : "3", "articleid" : "100001", "content" : 
......

执行成功,但是,document中只有update的userid,其他都没有了,这是一种覆盖模式。

  • $set局部修改
db.comment.update({userid:'1003'},{$set:{likenum:999}})
{ acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0 }
db.comment.find({},{userid:1,likenum:1})
{ _id: '0', userid: '1001', likenum: 10 }
{ _id: '1', userid: '1002', likenum: 1000 }
{ _id: '2', userid: '1100', likenum: 888 }
{ _id: '3', userid: '1004', likenum: 666 }
{ _id: '4', userid: '1003', likenum: 999 }
{ _id: '5', userid: '1003', likenum: 3000 }

上面的例子userid:1003有两条,如果都要改,加上multi:true

db.comment.update({userid:'1003'},{$set:{likenum:777}},{multi:true})
{ acknowledged: true,
  insertedId: null,
  matchedCount: 2,
  modifiedCount: 2,
  upsertedCount: 0 }
db.comment.find({},{userid:1,likenum:1})
{ _id: '0', userid: '1001', likenum: 10 }
{ _id: '1', userid: '1002', likenum: 1000 }
{ _id: '2', userid: '1100', likenum: 888 }
{ _id: '3', userid: '1004', likenum: 666 }
{ _id: '4', userid: '1003', likenum: 777 }
{ _id: '5', userid: '1003', likenum: 777 }
  • 对某个值自增
db.comment.update({userid:'1001'},{$inc:{likenum:1}})
{ acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0 }
db.comment.find({},{userid:1,likenum:1})
{ _id: '0', userid: '1001', likenum: 11 }
{ _id: '1', userid: '1002', likenum: 1000 }
{ _id: '2', userid: '1100', likenum: 888 }
{ _id: '3', userid: '1004', likenum: 666 }
{ _id: '4', userid: '1003', likenum: 777 }
{ _id: '5', userid: '1003', likenum: 777 }

删除

db.集合名称.remove(条件)
db.comment.remove({_id:'4'})
'DeprecationWarning: Collection.remove() is deprecated. Use deleteOne, deleteMany, findOneAndDelete, or bulkWrite.'
{ acknowledged: true, deletedCount: 1 }
db.comment.find({},{userid:1,likenum:1})
{ _id: '0', userid: '1001', likenum: 11 }
{ _id: '1', userid: '1002', likenum: 1000 }
{ _id: '2', userid: '1100', likenum: 888 }
{ _id: '3', userid: '1004', likenum: 666 }
{ _id: '5', userid: '1003', likenum: 777 }

提示即将弃用,尝试新的命令

db.comment.findOneAndDelete({_id:'0'})
{ _id: '0',
  articleid: '100000',
  content: '今天天气真好,阳光明媚',
  userid: '1001',
  nickname: 'Rose',
  createdatetime: 2022-01-21T12:57:49.081Z,
  likenum: 11,
  state: null }
db.comment.find({},{userid:1,likenum:1})
{ _id: '1', userid: '1002', likenum: 1000 }
{ _id: '2', userid: '1100', likenum: 888 }
{ _id: '3', userid: '1004', likenum: 666 }
{ _id: '5', userid: '1003', likenum: 777 }

如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。
索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排
序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。
官网文档:

Indexes

MongoDB索引使用B树数据结构(确切的说是B-Tree,MySQL是B+Tree)

索引的类型

  • 单字段索引
    MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。
  • 复合索引
    MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。
  • 其他索引
    地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。

索引

索引的管理操作

  • 索引的查看
db.collection.getIndexes()
db.comment.getIndexes()#默认索引
[ { v: 2, key: { _id: 1 }, name: '_id_' } ]

v-version

  • 在集合上创建索引

(1)单字段索引

db.collection.createIndex(keys, options)
db.comment.createIndex({userid:1})
'userid_1'
db.comment.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { userid: 1 }, name: 'userid_1' }
]

创建了userid的索引

keys :document
包含字段和值对的文档,其中字段是索引键,值描述该字段的索引类型。
对于字段上的升序索引,请指定值1;对于降序索引,请指定值-1。比如: {字段:1或-1} ,其中1 为指定按升序创建索引,如想按降序来创建索引指定为 -1 即可。
另外,MongoDB支持几种不同的索引类型,包括文本、地理空间和哈希索引。

options列表:

ParameterTypeDescription
backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加"background" 可选参数。 “background” 默认值为false。
uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为language.

(2)复合索引:对 userid 和 nickname 同时建立复合(Compound)索引:

db.comment.createIndex({nickname:1,userid:-1})
'nickname_1_userid_-1'
db.comment.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { userid: 1 }, name: 'userid_1' },
  {
    v: 2,
    key: { nickname: 1, userid: -1 },
    name: 'nickname_1_userid_-1'
  }
]

在这里插入图片描述

  • 删除索引

(1)删除某个索引

db.comment.dropIndex({userid:1})  #按字段删除
{ nIndexesWas: 3, ok: 1 }

db.comment.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  {
    v: 2,
    key: { nickname: 1, userid: -1 },
    name: 'nickname_1_userid_-1'
  }
]

db.comment.dropIndex('nickname_1_userid_-1')#按名字删除,不使用{}
{ nIndexesWas: 2, ok: 1 }

(2)删除全部用户索引

db.comment.dropIndexes()
{
  nIndexesWas: 3,
  msg: 'non-_id indexes dropped for collection',
  ok: 1
}
db.comment.getIndexes()
[ { v: 2, key: { _id: 1 }, name: '_id_' } ]#系统索引不会被删除

索引的使用

  • 执行计划
    分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是否基于索引查询等。
    语法:
db.collection.find(query,options).explain(options)

示例:

db.comment.find({userid:'1003'}).explain()
{ explainVersion: '1',
  queryPlanner: 
   { namespace: 'etaondb.comment',
     indexFilterSet: false,
     parsedQuery: { userid: { '$eq': '1003' } },
     maxIndexedOrSolutionsReached: false,
     maxIndexedAndSolutionsReached: false,
     maxScansToExplodeReached: false,
     winningPlan: 
      { stage: 'COLLSCAN',
        filter: { userid: { '$eq': '1003' } },
        direction: 'forward' },
     rejectedPlans: [] },
  command: { find: 'comment', filter: { userid: '1003' }, '$db': 'etaondb' },
  serverInfo: 
   { host: 'Alma',
     port: 27017,
     version: '5.0.5',
     gitVersion: 'd65fd89df3fc039b5c55933c0f71d647a54510ae' },
  serverParameters: 
   { internalQueryFacetBufferSizeBytes: 104857600,
     internalQueryFacetMaxOutputDocSizeBytes: 104857600,
     internalLookupStageIntermediateDocumentMaxSizeBytes: 104857600,
     internalDocumentSourceGroupMaxMemoryBytes: 104857600,
     internalQueryMaxBlockingSortMemoryUsageBytes: 104857600,
     internalQueryProhibitBlockingMergeOnMongoS: 0,
     internalQueryMaxAddToSetBytes: 104857600,
     internalDocumentSourceSetWindowFieldsMaxMemoryBytes: 104857600 },
  ok: 1 }

增加userid的index后:

db.comment.createIndex({userid:1})
'userid_1'
db.comment.find({userid:'1003'}).explain()
{ explainVersion: '1',
  queryPlanner: 
   { namespace: 'etaondb.comment',
     indexFilterSet: false,
     parsedQuery: { userid: { '$eq': '1003' } },
     maxIndexedOrSolutionsReached: false,
     maxIndexedAndSolutionsReached: false,
     maxScansToExplodeReached: false,
     winningPlan: 
      { stage: 'FETCH',
        inputStage: 
         { stage: 'IXSCAN',
           keyPattern: { userid: 1 },
           indexName: 'userid_1',
           isMultiKey: false,
           multiKeyPaths: { userid: [] },
           isUnique: false,
           isSparse: false,
           isPartial: false,
           indexVersion: 2,
           direction: 'forward',
           indexBounds: { userid: [ '["1003", "1003"]' ] } } },
     rejectedPlans: [] },
  command: { find: 'comment', filter: { userid: '1003' }, '$db': 'etaondb' },
  serverInfo: 
   { host: 'Alma',
     port: 27017,
     version: '5.0.5',
     gitVersion: 'd65fd89df3fc039b5c55933c0f71d647a54510ae' },
  serverParameters: 
   { internalQueryFacetBufferSizeBytes: 104857600,
     internalQueryFacetMaxOutputDocSizeBytes: 104857600,
     internalLookupStageIntermediateDocumentMaxSizeBytes: 104857600,
     internalDocumentSourceGroupMaxMemoryBytes: 104857600,
     internalQueryMaxBlockingSortMemoryUsageBytes: 104857600,
     internalQueryProhibitBlockingMergeOnMongoS: 0,
     internalQueryMaxAddToSetBytes: 104857600,
     internalDocumentSourceSetWindowFieldsMaxMemoryBytes: 104857600 },
  ok: 1 }

上面的例子可以看到查询方式的变化:

winningPlan:
{ stage: ‘COLLSCAN’,
filter: { userid: { ‘$eq’: ‘1003’ } },
变成:
winningPlan:
{ stage: ‘FETCH’,
inputStage:
{ stage: ‘IXSCAN’,
keyPattern: { userid: 1 },
indexName: ‘userid_1’,

COLLSCAN表示全集扫描
FETCH抓取
IXSCAN扫描Index

从compass看:
在这里插入图片描述

Documents Examined:6
检查了6次,即所有6条docments

而使用了index:userid后

在这里插入图片描述

检查次数变成了2,效率提高了;使用的方式和命令行的情况一致

  • 涵盖的查询
    Covered Queries
    当查询条件和查询的投影仅包含索引字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存。 这些覆盖的查询可以非常有效。

上面的例子进行查询
在这里插入图片描述

不查看_id,显示documents检查为0

> db.comment.find({userid:1,_id:0}).explain()
{
        "explainVersion" : "1",
        "queryPlanner" : {
                "namespace" : "etaondb.comment",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "_id" : {
                                                "$eq" : 0
                                        }
                                },
                                {
                                        "userid" : {
                                                "$eq" : 1
                                        }
                                }
                        ]
                },
                "queryHash" : "B3109953",
                "planCacheKey" : "349BB72E",
                "maxIndexedOrSolutionsReached" : false,
                "maxIndexedAndSolutionsReached" : false,
                "maxScansToExplodeReached" : false,
                "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                                "userid" : {
                                        "$eq" : 1
                                }
                        },
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "_id" : 1
                                },
                                "indexName" : "_id_",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "_id" : [ ]
                                },
                                "isUnique" : true,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "_id" : [
                                                "[0.0, 0.0]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "command" : {
                "find" : "comment",
                "filter" : {
                        "userid" : 1,
                        "_id" : 0
                },
                "$db" : "etaondb"
        },
        "serverInfo" : {
                "host" : "Alma",
                "port" : 27017,
                "version" : "5.0.5",
                "gitVersion" : "d65fd89df3fc039b5c55933c0f71d647a54510ae"
        },
        "serverParameters" : {
                "internalQueryFacetBufferSizeBytes" : 104857600,
                "internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
                "internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
                "internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
                "internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
                "internalQueryProhibitBlockingMergeOnMongoS" : 0,
                "internalQueryMaxAddToSetBytes" : 104857600,
                "internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
        },
        "ok" : 1
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值