MongoDB 基础学习记录

MongoDB 基础

mongoDB 是由 C++语言编写,基于分布式文件存储的开源数据库系统,是一个 nosql 数据库.

在高负载的情况下,添加更多的节点,保证服务器性能,MongoDB 旨在为 web 引用提供可扩展的高性能存储解决方案,将数据存储为给文档,

数据结构由键值(key,value)对组成,MongoDB 文档类似于 json 对象,字段值可以包含其他文档,数据以及文档数组.

主要特点

面向文档:MongoDB 存储的数据采用 JSON 样式的 BSON(二进制 JSON)文档格式,可以直接映射到应用程序的对象模型。这种面向文档的模型使得数据的存储和查询更加灵活和方便。

高性能:MongoDB 具有高度并行化和低延迟的读写操作,支持水平扩展以处理大量数据。它还支持基于内存的操作,可以提供非常快的查询速度。

良好的可扩展性:MongoDB 的架构设计适合横向扩展,它可以通过添加更多的节点来处理更大规模的数据和负载。同时,它支持自动分片,可以将数据分布在多个服务器上进行负载均衡。

强大的查询功能:MongoDB 提供了丰富的查询功能,包括范围查询、全文搜索、正则表达式等,并支持聚合查询和地理空间查询。此外,它还支持二级索引,可以根据需求对不同字段建立索引。

灵活的数据模型:MongoDB 的文档模型允许存储具有不同结构和字段的文档,无需事先定义表结构。这种灵活性使得应用程序可以随时更改和扩展数据模型,而无需任何迁移过程。

多种数据一致性选项:MongoDB 提供了多种数据一致性选项,可以在数据的一致性和性能之间进行权衡。开发人员可以根据需求选择合适的副本集或分片策略,以满足应用程序的需求。

社区支持和生态系统:MongoDB 有一个庞大的用户社区和活跃的开发者社区,提供了丰富的资源和支持。此外,MongoDB 还有许多附加工具和第三方库,可以帮助用户更好地使用和管理数据库。

  • 1,MongoDB 是一个面向文档存储的数据库,操作简单
  • 2,你可以在 MongoDB 记录设置任何属性的索引
  • 3,可以通过本地或者网络创建数据镜像,
  • 4,支持网络分片
  • 5,丰富的查询表达式,查询指令使用 json 形式,可以在文档中内嵌对象和数组
  • 6,使用 update 命令可以实现替换完成文档数据或者一些指定字段的更新,
  • 7,map/reduce 主要是用来对统计数据进行批量出和操作,
  • 8,map 函数调用的 emit(key,value)遍历集合中所有记录,将 key 于 value 传给 Reduce 函数进行处理,
  • map 函数和 reduce 函数使用 js 编写的,并可以通过 db.runCommand 或 mapreduce 命令来执行 MapReduce 操作。
  • GridFS 是 MongoDB 中的一个内置功能,可以用于存放大量小文件,
  • mongoDB 允许在服务器端执行脚本,可以用 js 编写某个函数,直接在服务器端执行,也可以把函数的定义存储在服务端下,下次直接调用了,
  • MongoDB 支持多种变成语言,Python,c++,php,c#等多种,

mongoDB 概念解析

将于关系数据库类比解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S5Ulzncu-1690278972184)(./images/2022-10-20-16-48-43.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4j5Stjt6-1690278972185)(./images/2022-10-20-16-49-01.png)]

这里就可以很多看出,这里是以 json 字符串方式的匹配.

数据库

MongoDB 的单个实例可以容纳多个独立的数据库,每各都有自己的集合和权限,不同的数据库也放置在不同的文件中,

show dbs : 可以显示所有数据的列表,

db: 可以显示当前数据库对象或集合

use: 指定一个连接到一个数据库

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

admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。

local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合

config: 当 Mongo 用于分片设置时,config 数据库在内部使用,用于保存分片的相关信息。

文档(Document)

文档是一组键值对,文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,

例如:

json 复制代码
{ "site": "www.runoob.com", "name": "菜鸟教程" }

需要注意的是:

1,文档中的键值是有序的,

2,文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型

3,mongoDB 区分类型和大小写

4,文档中不能有重复的键

5,文档中的键是字符串,使用 utf-8

文档键命令要求:

键不能有空字符,一般是来识别键结尾,

.和$有特殊意义,只有在特定环境下使用

以下划线_开头的键是保留的(不严格要求)

注意: 在 MongoDB 中,因为它本身具有的灵活性,所以不要求一个集合中的文档的字段格式必须要相同,这于关系型数据很不大同。

其中单个文档具有不同字段,那么也就是具有了不同的数据长度,例如:

sql 复制代码
{ _id: 1, name: "John", age: 20, grade: "A" }
{ _id: 2, name: "Jane", age: 22, major: "Computer Science", GPA: 3.5 }

需要注意的是: 查询操作的时候,对于缺少该字段的文档,不会返回控制,而是直接忽略,在结果中不会展示。

集合

集合就是 MongoDB 文档组,类似于关系型数据库中的表

集合存在于数据库中,集合没有固定的结构,这意味着对集合可以插入不同格式和类型的数据,当第一个文档被插入的时候,集合就已经被创建了.

集合命令不能以"system"开头,这是为了系统集合保留前缀.

用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。

集合名不能是空字符串""。

集合名不能含有\0 字符(空字符),这个字符表示集合名的结尾。

capped collections

capped collections 就是固定大小的集合,它有很高的性能以及队列过期的特性,

capped collections 是高性能自动维护对象的插入顺序,它非常适合类似记录日志的功能和标准的 collection 不同,你必须要显示的创建一个 capped collections,指定它的大小,单位是字节,是可以提前分配的,

capped collections 可以按照文档的插入顺序保存到集合中,而且这些文档在磁盘上存放的位置,也是按照顺序来保存的,所以当我们更新 capped collections 中文档的时候,更新后的文档的不能超过之前文档的大小,这样就可以保持所有文档在磁盘上的位置一直保持不变.

可以很好的提高插入数据额效率,要注意的是:指定的存储大小包含了数据库头信息.

db.createCollection("mycoll", {capped:true, size:100000})

在 capped collection 中,你能添加新的对象。

能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。

使用 Capped Collection 不能删除一个文档,可以使用 drop() 方法删除 collection 所有的行。

删除之后,你必须显式的重新创建这个 collection。

在 32bit 机器中,capped collection 最大存储为 1e9( 1X109)个字节。

元数据

数据库的信息是存储在集合中,他们使用了系统的命令空间

dbname.system.*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ka0pWWiM-1690278972186)(./images/2022-10-20-17-17-01.png)]

MongoDB 的数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fhmm99qw-1690278972187)(./images/2022-10-20-17-18-36.png)]

Object 类型:

object 类似是唯一主键,可以很快的去生成和排序,包含了 12bytes,

含义:

前 4 个字节表示创建的 unix 时间戳,后 3 个是机器标识码,然后是进程 id,然后是随机数,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7Lac1o0-1690278972188)(./images/2022-10-20-17-20-58.png)]

MongoDB 中存储的文档必须有个_id 键,这个键的值可以是任何类型的,默认是个 object 对象,

由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:

sql 复制代码
> var newObject = ObjectId()
> newObject.getTimestamp()
ISODate("2017-11-25T07:21:10Z")

objectld 转为字符串: newObject.str

String(字符串):用于存储文本数据,例如姓名、地址、描述等。

Number(数字):用于存储数值类型的数据,包括整数和浮点数。

Boolean(布尔值):存储 true 或 false 两个取值。

Date(日期):用于存储日期和时间,以 ISO 格式进行存储。

Object(对象):用于存储复杂的数据结构,可以包含多个字段。

Array(数组):用于存储多个值的列表。

Binary Data(二进制数据):用于存储二进制数据,例如图片、音频或视频等。

ObjectId(对象 ID):用于存储文档的唯一标识符,在集合中自动生成。

Null(空值):表示没有值的字段。

Undefined(未定义):表示字段未定义或不存在。

Regular Expression(正则表达式):用于存储正则表达式模式。

除了上述常见的数据类型之外,MongoDB 还支持一些特殊的数据类型,例如 GeoJSON(地理空间数据)、Timestamp(时间戳)等,以满足不同类型数据的存储需求。

时间戳

BSON 有一个特殊的时间戳类型用于 MongoDB 内部使用,与普通的 日期 类型不相关。 时间戳值是一个 64 位的值。其中:

前 32 位是一个 time_t 值,

后 32 位是在某秒中操作的一个递增的序数

在单个 mongod 实例中,时间戳的值通常是唯一的,在复制集群中,oplog 有一个 ts 字段,这个字段中的值是使用 bson 时间戳表示的操作时间.

MongoDB - 连接

mongdb 服务安装之后,需要先创建两个目录:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6euW6Fb-1690278972189)(2023-06-18-16-18-07.png)]

创建对应 data 目录,然后使用下面的启动命令启动,

启动 MongoDB 服务:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

回显成功,即可.

进入管理 shell: (6.0 之后,需要自己安装 shell 工具)

到 MongoDB 的安装/bin 目录下,执行: ./mongo

mongodb://[username:password@]host1[:port1],host2[:port2],...[,hostN[:portN]]][/[database][?options]]

mongodb:// 这是固定的格式,必须要指定。

username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登录这个数据库

host1 必须的指定至少一个 host, host1 是这个 URI 唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。

portX 可选的指定端口,如果不填,默认为 27017

/database 如果指定 username:password@,连接并验证登录指定数据库。若不指定,默认打开 test 数据库。

?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对 name=value,键值对之间通过&或;(分号)隔开

mongo 支持多个连接:

连接 replica pair, 服务器 1 为 example1.com 服务器 2 为 example2。: mongodb://example1.com:27017,example2.com:27017

连接 replica set 三台服务器 (端口 27017, 27018, 和 27019): mongodb://localhost,localhost:27018,localhost:27019

用户身份认证

db.auth("username","password")

使用 rpm 安装的 mongodb.进入命令行:

mongoDB 语法

创建数据库

建库语句:

use DATABASE_NAME

(如果数据库不存在,则进行创建,否则切换到指定的数据库)

查看所有数据库:

show dbs;

注意: 库中没有数据时候是无法查看的,需要向其中插入数据,在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

删除数据库:

db.dropDatabase()

默认会删除当前的库,可以使用 db,查看当前的数据库名

使用 use 进入到指定库中,然后执行 db.dropDatabase().

创建集合:

db.createCollection(name,options)

说明:

name: 要创建的集合名称,

options: 可选参数,指定有关内存大小及索引的选项.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-78jjzkBV-1690278972190)(./images/2022-11-09-18-14-43.png)]

在插入文档时,MongoDB 首先会检查固定的集合的 size 字段,然后检查 max 字段.

sql 复制代码
db.createCollection("runoob")

db.createCollection("mycol", { capped : true, autoIndexId : true, size :
   6142800, max : 10000 } )
{ "ok" : 1 }

如果查看已经有的集合,可以使用 show collections 或 showtables 命令:
在 MongoDB 中,你不需要创建集合,当你插入一些文档,mongoDB 会自动创建集合,隐式创建的方式.

删除集合:

db.collection_name.drop()

如果删除成功则会返回 true,否则返回 false

插入文档

文档的数据结构和 json 基本一样,所有存储在集合中的数据都是 bson 格式,

插入:

mongoDB 中使用的 inset()或 save()方法向集合中插入文档:

db.COLLECTION_NAME.insert(document)

db.COLLECTION_NAME.save(document)

save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 来代替。

insert(): 如果插入的数据主键已经存在,会抛出异常,提示主键已经重复,不保存当前的数据,

db.collection.insertMany() 用于向集合插入一个多个文档,语法格式如下,最新用法:

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)
document:要写入的文档。
writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求
ordered:指定是否按顺序写入,默认 true,按顺序写入。

以上实例 col 是我们的集合名称,如果该集合在不在数据库中,则会自动创建给文档的集合,并插入新的文档. 这种方式就是隐式创建集合,在写入文档时候,创建集合.

也可以将数据定义为一个变量,document={}

然后再将变量传入,db.col.insert(document)

更新文档

update()方法用于更新已经存在的文档,语法格式:

bash 复制代码
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
db.users.updateMany(
  { age: { $gte: 30 } },   // 匹配条件,找出age大于等于30的文档
  { $set: { status: "active" } }  // 更新操作,将匹配的文档的status字段设置为"active"
);

query: update 的查询条件,类型 where 子句,

update: update 的对象和一些更新的操作符等,也可以理解为 sql update 查询内 set 后面的值,

upsert: 可选,表示如果存在 update 的记录,是否插入 objnew,true 为插入,默认 false

multi: 默认是 false,只更新找到的第一条记录,如果这个参数为 ture,就把这个条件查询出来的多条记录全部更新

writeConcern :可选,抛出异常的级别。

在更新文档时,可以使用多种操作符,包括 s e t 、 set、 set、inc、 u n s e t 等。 unset 等。 unset等。inc 操作符用于递增或递减字段的值,而 s e t 操作符用于设置字段的值。 set操作符用于设置字段的值。 set操作符用于设置字段的值。unset(用于删除字段)、$push(用于向数组添加元素)

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   # 输出信息
> db.col.find().pretty()
{
        "_id" : ObjectId("56064f89ade2f21f36b03136"),
        "title" : "MongoDB",
        "description" : "MongoDB 是一个 Nosql 数据库",
        "by" : "菜鸟教程",
        "url" : "http://www.runoob.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}
>

以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。

db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
save()方法

save()方法是通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入,已经废弃

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

document : 文档数据。

writeConcern :可选,抛出异常的级别。

删除文档

建议使用 deleteOne()方法来删除匹配条件的单个文档,或者使用 deleteMany()方法来批量删除匹配条件的多个文档。

下面是一个示例,演示如何使用 deleteOne()方法删除匹配条件的单个文档:

// 删除名为 "users" 的集合中匹配条件的数据(删除第一个匹配的文档)

db.users.deleteOne({ age: { $gte: 30 } });

const result = await db.users.deleteMany({ age: { $gte: 30 } });

console.log(result.deletedCount);

deleteMany()方法将删除所有与匹配条件匹配的文档,而不仅仅是第一个匹配文档。

查询操作

mongodb 中的表达式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3vY9Ve7v-1690278972191)(./images/2023-07-20-18-28-27.png)]

查询语法:

sql 复制代码
查询全部: db.collection.find() 不带参数

回显指定字段: db.collection.find({},{title:1,_id:0}) 1表示显示,0表示不显示,其中的第一个{}表示查询条件,第二个{}表示要显示的字段,_id默认是显示的,如果不显示,需要设置为0

查询判断: db.collection.find({likes:{$gt:100}}) 查询likes大于100的数据 $gt表示大于,$lt表示小于,$gte表示大于等于,$lte表示小于等于,$ne表示不等于
db.collection.find({status:"A"}) 这种表示返回status等于A的数据的全部字段信息。

也可以使用多个匹配条件:
db.collection.find({
    staues:"A",
    likes:{$gt:100}
})
使用逻辑判断:
db.collection.find({
    $or:[
        {status:"A"},
        {likes:{$gt:100}}
    ]
}) 表示或的关系
db.collection.find({
    $and:[
        {status:"A"},
        {likes:{$gt:100}}
    ]
}) 表示与的关系

多条件查询:
db.collection.find({
    $and:[
        {status:"A"},
        {likes:{$gt:100}}
    ],
    $or:[
        {title:"MongoDB 教程"},
        {title:"C# 教程"}
    ]
})
正则匹配:
db.collection.find({title:/^MongoDB/}) 表示title以MongoDB开头的数据

匹配嵌套文档:

sql 复制代码
测试数据:
db.collection.insertMany([
    { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
    { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
    { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
    { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
    { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
])
在这里,size域是一个嵌套文档。要匹配嵌套文档,必须使用引号将整个嵌套文档括起来,例如:
db.collection.find({size: {h: 14, w: 21, uom: "cm"}},{_id:0})
这里的匹配格式和位置很重要,不能出现错误,否则无法匹配到数据。


在嵌套的字段上查询,使用点号(.)来指定嵌套字段,例如:
指定sized对象里面的uom属性值查询:
db.collection.find({"size.uom": "in"})

查询数组结构:
测试数据:
db.size.insertMany([
    {item:"journal",qty:[5,15]},
    {item:"notebook",qty:[10,20]},
    {item:"paper",qty:[5,10]},
    {item:"planner",qty:[0,10]},
    {item:"postcard",qty:[15,15]}
])

精确查询:
db.collection.find({qty:{$eq:5}})
包含查询:
db.collection.find({qty:{$in:[5,15]}},{_id:0})
不包含查询:
db.collection.find({qty:{$nin:[5,15]}},{_id:0})
数组长度查询:
db.collection.find({qty:{$size:2}},{_id:0}) # 查询qty数组长度为2的数据

查询数据中满足指定条件的元素,使用$elemMatch操作符,例如:
实例数据:
{
  _id: 1,
  scores: [
    { subject: 'Math', score: 90 },
    { subject: 'English', score: 85 },
    { subject: 'Science', score: 92 }
  ]
}
现在我们想查询 scores 数组中其中一个科目的分数大于等于90的文档,可以使用 $elemMatch 操作符来实现:
db.collection.find({scores:{$elemMatch:{score:{$gte:90}}}})
如果要查询科目
db.collection.find({scores:{$elemMatch:{subject:"Math"}}})
如果要组合查询
db.collection.find({scores:{$elemMatch:{subject:"Math",score:{$gte:90}}}})
表示查询 scores 数组中有一个元素的 subject 域等于 "Math",并且 score 域大于等于 90 的文档。

文档的排序插查询:

sql 复制代码
通过关键字sort()来实现排序,1表示升序,-1表示降序,例如:
db.collection.find({status:"A"}).sort({user_id:1}}
注意,排序操作,sort是在find之外,而不是在find里面,否则会报错。
同时在find内部做匹配操作,然后在find外部做排序操作。

查询总数:

sql 复制代码
mongodb中也是通过count方法进行统计。
db.collection.find({status:"A"}).count()  --指定字段查询总数
db.collection.find({user_id:{$exists:true}}).count()
-- 其中的$exists表示user_id字段存在的数据,如果不加$exists,表示user_id字段不存在的数据。
-- 该操作符主要用于检查文档中某个字段是否存在,如果存在返回true,否则返回false。

去重处理:

sql 复制代码
db.collection.distinct({status:"A"})  -- 去重status字段
db.collection.aggregate([{$group:{_id:"$status"_}]) -- 去重status字段

获取指返回条数,分页查询方法

使用 find().limit()方法来指定返回的条数,例如:

sql 复制代码
db.collection.find().limit(2)
指定返回值的某条记录
db.collection.find().limit(5).skip(10)
对比:select * from table limit 10,5

使用 limit 操作符限制返回的文档数。limit 操作符接受一个整数参数,表示需要返回的文档数。

使用 skip 操作符指定跳过的文档数。skip 操作符接受一个整数参数,表示需要跳过的文档数。

例如,假设有一个名为 books 的集合,我们需要查询第二页的 10 个文档。可以按照以下步骤进行操作:

计算每页的文档数。假设每页显示 10 个文档,所以每次查询应该设置 limit 为 10。

计算要跳过的文档数。对于第二页,我们需要跳过前 10 个文档,所以 skip 值为 10。

查询 sql 语句的执行情况:

sql 复制代码
与mysql类似,采用explain语句来查看
db.collection.find().explain()
使用所索引的情况
db.collection.find({status:"A"}).explain()

就可以查看到该 sql 语言执行过程中是否采用了索引,以及它的索引类型等信息。

语句返回的基本内容:

json 复制代码
{
  "queryPlanner": {
    "plannerVersion": 1, //查询计划版本
    "namespace": "sang.sang_collect", //要查询的集合
    "indexFilterSet": false, //是否使用索引
    "parsedQuery": {
      //查询条件
      "x": {
        //查询条件字段
        "$eq": 1.0 //查询条件值
      }
    },
    "winningPlan": {
      //最终执行的查询计划
      "stage": "COLLSCAN", //查询的方式,常见有collscan/全表扫描, indexscan/索引扫描, FETCH/根据索引去检索文档获取数据, SHARD_MERGE/分片合并结果 IDHACK/根据_id去检索文档获取数据
      "filter": {
        //查询条件
        "x": {
          //查询条件字段
          "$eq": 1.0 //查询条件值
        }
      },
      "direction": "forward" //查询方向 forward/正向,backward/反向 通常是采用正向索引查询
    },
    "rejectedPlans": [] //被拒绝的查询计划
  },
  "serverInfo": {
    //服务器信息
    "host": "localhost.localdomain", //主机名
    "port": 27017, //端口号
    "version": "3.4.9", //版本号
    "gitVersion": "876ebee8c7dd0e2d992f36a848ff4dc50ee6603e" //git版本号
  },
  "ok": 1.0 //是否成功
}

explain()也可以接受一个参数,该参数是一个文档,用于指定 explain 的模式,例如:

db.collection.find().explain("executionStats")

db.collection.find().explain("allPlansExecution")

db.collection.find().explain("queryPlanner")

参考链接:'https://blog.csdn.net/user_longling/article/details/83957085'

命令总结:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZDsDnEyr-1690278972193)(./images/2023-06-23-12-56-51.png)]

mongdb 中的索引类型

mongdb 的索引底层采用的是 b-tree,

这里简单介绍一下大概的索引类型,后面会详细介绍.

单键索引类型:

它支持所有数据类型中的单个字段的索引,并且可以在文档的任何字段上定义,

对于单个字段索引,索引建的排序无关紧要,它是从任一方向上开始读取索引,所以不注重顺序

特殊: 过期索引 TTL

其中 TTL 索引是,支持文档在一定时间之后,自动过期删除的,并且目前只能在单字段索引上建立,且字段类型必须为日期类型...

db.集合名.createIndex({"日期字段":排序方式}, {expireAfterSeconds: 秒数})

复合索引

我们需要在多个字段的基础上搜索表/集合,这是非常频繁的。 如果是这种情况,我们可能会考虑在 MongoDB 中制作复合索引。 复合索引支持基于多个字段的索引,这扩展了索引的概念并将它们扩展到索引中的更大域。

需要注意: 字段顺序,索引方向

db.集合名.createIndex( { "字段名 1" : 排序方式, "字段名 2" : 排序方式 } )

多键索引

针对属性包含数组数据的情况,MongoDB 支持针对数组中每一个 element 创建索引,Multikey indexes 支持 strings,numbers 和 nested documents

地理空间索引(Geospatial Index)

针对地理空间坐标数据创建索引。

2dsphere 索引,用于存储和查找球面上的点

2d 索引,用于存储和查找平面上的点

db.company.insert(
	{
		loc : { type: "Point", coordinates: [ 116.482451, 39.914176 ] },
		name: "大望路地铁",
		category : "Parks"
	}
)
db.company.ensureIndex( { loc : "2dsphere" } )
# 参数不是1或-1,为2dsphere 或者 2d。还可以建立组合索引。
db.company.find({
	"loc" : {
		"$geoWithin" : {
		"$center":[[116.482451,39.914176],0.05]
		}
	}
})

全文索引

提供了针对 string 内容的文本查询,text index 支持持任意属性值为 string 或 string 数组元素的索引查询。注意:一个集合仅支持最多一个 Text Index,中文分词不理想 推荐 ES。

db.集合.createIndex({"字段": "text"})

db.集合.find({"KaTeX parse error: Expected '}', got 'EOF' at end of input: text": {"search": "coffee"}})

哈希索引 (Hashed Index)

针对属性的哈希值进行索引查询,当要使用 Hashed index 时,MongoDB 能够自动的计算 hash 值,无需程序计算 hash 值。注:hash index 仅支持等于查询,不支持范围查询。

db.集合.createIndex({"字段": "hashed"})

索引操作

索引的查看: db.comment.getIndexs() ,查看所有的索引

索引的创建:

db.collection.createIndex(keys,options)

其中 key,是索引的字段,option 是对索引的具体设置.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mq5ywxAQ-1690278972194)(./images/2023-06-18-16-50-16.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fCpRli5c-1690278972194)(2023-06-18-16-51-11.png)]

db.mycol.createIndex({userid:1}) 这里 1 代表升序,-1 是降序

索引的删除: db.collection.dropIndex(index)

相关推荐
Young_2022020210 分钟前
学习笔记——KMP
笔记·学习
Leo.yuan23 分钟前
数据量大Excel卡顿严重?选对报表工具提高10倍效率
数据库·数据分析·数据可视化·powerbi
行然梦实26 分钟前
学习日记_20241110_聚类方法(K-Means)
学习·kmeans·聚类
马船长31 分钟前
制作图片木马
学习
Runing_WoNiu32 分钟前
MySQL与Oracle对比及区别
数据库·mysql·oracle
秀儿还能再秀43 分钟前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
WCF向光而行1 小时前
Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)
笔记·学习
天道有情战天下1 小时前
mysql锁机制详解
数据库·mysql
看山还是山,看水还是。1 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
谷新龙0011 小时前
Redis运行时的10大重要指标
数据库·redis·缓存