Mongodb快速入门

一、概述

1.1介绍

MongoDB是一个`基于分布式文件存储的数据库`。由C++语言编写。旨在`为WEB应用提供可扩展高性能数据存储解决方案`。(并不是单纯的内存数据库),官方地址 https://www.mongodb.com/

操作语法与 JavaScript 类似,容易上手,学习成本低
Mongodb 中有三个重要概念需要掌握
数据库(database) 数据库是一个数据仓库,数据库服务下可以创建很多数据库,数据库中可以存放很多集合

集合(collection) 集合类似于 JS 中的数组,在集合中可以存放很多文档
文档(document) 文档是数据库中的最小单位,类似于 JS 中的对象

特点

  • 面向集合存储,易存储对象类型的数据

  • 支持查询,以及动态查询

  • 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言

  • 文件存储格式为BSON(一种JSON的扩展)

  • 支持复制和故障恢复和分片

  • 支持事务支持

  • 索引 聚合 关联....

应用场景

  • 游戏应用:使用云数据库MongoDB作为游戏服务器的数据库存储用户信息。用户的游戏装备、积分等直接以内嵌文档的形式存储,方便进行查询与更新。
  • 物流应用:使用云数据库MongoDB存储订单信息,订单状态在运送过程中会不断更新,以云数据库MongoDB内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来,方便快捷且一目了然。
  • 社交应用:使用云数据库MongoDB存储用户信息以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。并且,云数据库MongoDB非常适合用来存储聊天记录,因为它提供了非常丰富的查询,并在写入和读取方面都相对较快。
  • 视频直播:使用云数据库MongoDB存储用户信息、礼物信息等。
  • 大数据应用:使用云数据库MongoDB作为大数据的云存储系统,随时进行数据提取分析,掌握行业动态。

1.2安装

详情请见Docker容器(五)Docker Compose

启动

bash 复制代码
mongo --host example.com:27017 -u myUser -p myPassword

图形化管理工具

我们可以使用图形化的管理工具来对 Mongodb 进行交互,这里演示两个图形化工具

Robo 3T 免费 Releases · Studio3T/robomongo · GitHub

Navicat 收费 Navicat 中国 | 支持 MySQL、Redis、MariaDB、MongoDB、SQL Server、SQLite、Oracle 和 PostgreSQL 的数据库管理

1.3相关概念

文档

文档集合中一条条记录,是一组键值(key-value)对(即 BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

  • 多个键及其关联的值有序地放在一起就构成了文档。
  • MongoDB文档类似于JSON对象。字段的值可以包括其他文档,数组和文档数组。

{"greeting":"hello,world"}这个文档只有一个键"greeting",对应的值为"hello,world"。多数情况下,文档比这个更复杂,它包含多个键/值对。

例如:{"greeting":"hello,world","foo": 3} 文档中的键/值对是有序的,下面的文档与上面的文档是完全不同的两个文档。{"foo": 3 ,"greeting":"hello,world"}

文档中的值不仅可以是双引号中的字符串,也可以是其他的数据类型,例如,整型、布尔型等,也可以是另外一个文档,即文档可以嵌套。文档中的键类型只能是字符串

使用文档的优点是:

  • 文档(即对象)对应于许多编程语言中的本机数据类型
  • 嵌入式文档和数组减少了对昂贵连接的需求
  • 动态模式支持流畅的多态性

集合

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

集合存在于数据库中,一个库中可以创建多个集合。每个集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

既然集合中可以存放任何类型的文档,那么为什么还需要使用多个集合?

数据库

​ `mongodb中的库就类似于传统关系型数据库中库的概念,用来通过不同库隔离不同应用数据`。mongodb中可以建立多个数据库。每一个库都有自己的集合和权限,不同的数据库也放置在不同的文件中。默认的数据库为"test",数据库存储在启动指定的data目录中。

MongoDB 中存在以下系统数据库。

  • Admin 数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin 数据库中,那么该用户就自动继承了所有数据库的权限。
  • Local 数据库:这个数据库永远不会被复制,可以用来存储本地单台服务器的任意集合。
  • Config 数据库:当MongoDB 使用分片模式时,config 数据库在内部使用,用于保存分片的信息。

与关系数据库管理系统区别

|-----------------|------------------|
| RDBMS | MongoDB |
| 数据库<database> | 数据库<database> |
| 表<table> | 集合<collection> |
| 行<row> | 文档<document> |
| 列<colume> | 字段<field> |

数据模型

一个MongoDB 实例可以包含一组数据库,一个DataBase 可以包含一组Collection(集合),一个集合可以包含一组Document(文档)。

一个Document包含一组field(字段),每一个字段都是一个key/value pair

  • key: 必须为字符串类型
  • value:可以包含如下类型
    • 基本类型,例如,string,int,float,timestamp,binary 等类型
    • 一个document
    • 数组类型

二、MongoDB基本操作及增删改查

2.1数据库操作

登陆数据库

mongo

查看数据库选择数据

bash 复制代码
show databases;

注意: use 代表创建并使用,当库中没有数据时默认不显示这个库

选择数据库

bash 复制代码
use 数据库名 

如果切换到一个没有的数据库,例如use admin2,那么会隐式创建这个数据库。(后期当该数据库有数据时,系统自动创建)

显示当前所在的数据库

bash 复制代码
db

删除当前数据库

bash 复制代码
use 库名
db.dropDatabase()

2.2集合操作

创建集合

bash 复制代码
db.createCollection('集合名称', [options])
字段 类型 描述
capped 布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。
size 数值 (可选)为固定集合指定一个最大值,即字节数。 如果 capped 为 true,也需要指定该字段。
max 数值 (可选)指定固定集合中包含文档的最大数量。

查看集合

bash 复制代码
show collections

删除集合

bash 复制代码
`db.集合名.drop()`

重命名集合

bash 复制代码
db.集合名.renameCollection('newName')

2.3文档操作

插入文档

bash 复制代码
db.集合名.insert(文档对象);
db.aaa.insert({_id: "123"});

如果集合存在,那么直接插入数据。如果集合不存在,那么会隐式创建。

示例:在test2数据库的c1集合中插入数据(姓名叫webopenfather年龄18岁)

bash 复制代码
use test2 db.c1.insert({uname:"webopenfather",age:18})
  • 数据库和集合不存在都隐式创建
  • 对象的键统一不加引号(方便看),但是查看集合数据时系统会自动加
  • mongodb会给每条数据增加一个全球唯一的_id

一次性插入多条数据

传递数据,数组中写一个个JSON数据即可

bash 复制代码
db.aaa.insert([     {uname:"z3", age:3},     {uname:"z4", age:4},     {uname:"w5", age:5} ])

快速插入10条数据

由于mongodb底层使用JS引擎实现的,所以支持部分js语法。因此:可以写for循环

bash 复制代码
for (var i=1; i<=10; i++) {     db.aaa.insert({uanme: "a"+i, age: i}) }

查询文档

bash 复制代码
db.集合名.find(条件[,查询的列])
_id 是 mongodb 自动生成的唯一编号,用来唯一标识文档
条件 写法
查询所有的数据 {}或者不写
查询age=6的数据 {age:6}
既要age=6又要性别=男 {age:6,sex:'男'}
查询的列(可选参数) 写法
查询全部列(字段) 不写
只显示age列(字段) {age:1}
除了age列(字段)都显示 {age:0}
bash 复制代码
db.aaa.find()

其他语法

bash 复制代码
db.集合名.find({
            键:{运算符:值}
            })
运算符 作用
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in in
$nin not in

更新文档

bash 复制代码
 db.集合名称.update(
     <query>,
     <update>,
     {
       upsert: <boolean>,
       multi: <boolean>,
       writeConcern: <document>
     }
  );

参数说明:

  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如,,inc...)等,也可以理解为sql update查询内set后面的。
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。
    update 方法默认只会更新符合查询条件的第一条文档。这是因为在进行更新操作时,MongoDB默认只会更新匹配的第一条文档,除非你显式指定 multi: true 选项,这样才会更新所有匹配的文档。例如,你可以这样使用 update 方法来更新所有匹配的文档:
    db.集合名.update(查询条件, 更新操作, { multi: true })

删除文档

bash 复制代码
db.集合名称.remove(
     <query>,
     {
       justOne: <boolean>,
       writeConcern: <document>
     }
  )

参数说明:

  • query :可选删除的文档的条件。
  • justOne : 可选如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
  • writeConcern :可选抛出异常的级别。

总结

插入文档
db.集合名.insert(文档对象);

查询文档
db.集合名.find(查询条件)

_id 是 mongodb 自动生成的唯一编号,用来唯一标识文档

更新文档
db.集合名.update(查询条件,新的文档) 默认全部子弹更新
db.集合名.update({name:'张三'},{$set:{age:19}}) 指定字段更新

删除文档
db.集合名.remove(查询条件)

2.4文档查询

MongoDB 查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所有文档。

如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:

bash 复制代码
db.集合名称.find().pretty()

注意: pretty() 方法以格式化的方式来显示所有文档。

and

bash 复制代码
db.集合名称.find({key1:value1, key2:value2,...}).pretty()

类似于 WHERE 语句:WHERE key1=value1 AND key2=value2

OR

MongoDB OR 条件语句使用了关键字 **$or**,语法格式如下:

bash 复制代码
db.集合名称.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

类似于 WHERE 语句:WHERE key1=value1 or key2=value2`

AND 和 OR 联合

bash 复制代码
db.集合名称.find({"age": {$gt:50}, $or: [{"name": "编程不良人"},{"name": "MongoDB"}]}).pretty();

类似SQL语句为:'where age >50 AND (name = '编程不良人' OR name = 'MongoDB')'

数组中查询

bash 复制代码
> db.aaa.insert({ "_id" : 11, "age" : 29, "likes" : [ "看电视", "读书xx", "美女" ], "name" : "不良人_xx_11" })
-- 执行数组查询
> db.users.find({likes:"看电视"})
-- $size 按照数组长度查询
> db.users.find({likes:{$size:3}});

模糊查询

bash 复制代码
db.aaa.find({likes:/良/});

类似 SQL 中为 'where name like '%name%

排序

bash 复制代码
db.集合名称.find().sort({name:1,age:1}),
- 1 升序  -1 降序

类似 SQL 语句为: 'order by name,age

分页

bash 复制代码
db.集合名称.find().sort({条件}).skip(start).limit(rows);

db.集合名称.find().sort({条件}).skip(start).limit(rows);

总条数

bash 复制代码
> db.集合名称.count();
> db.集合名称.find({"name":"编程不良人"}).count();

类似于 SQL 语句为: 'select count(id) from ....

去重

bash 复制代码
db.集合名称.distinct('字段')

类似于 SQL 语句为: 'select distinct name from ....

三、MongoDB存储数据类型

BSON是一种类JSON的二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSONJSON没有的一些数据类型,如DateBinData类型,MongoDB使用BSON做为文档数据存储和网络传输格式。、

数字

shell默认使用64位浮点型数值,如下:

bash 复制代码
db.sang_collec.insert({x:3.1415926})
db.sang_collec.insert({x:3})

对于整型值,我们可以使用NumberInt或者NumberLong表示,如下:

bash 复制代码
db.sang_collec.insert({x:NumberInt(10)})
db.sang_collec.insert({x:NumberLong(12)})

字符串

字符串也可以直接存储,如下:

bash 复制代码
db.sang_collec.insert({x:"hello MongoDB!"})

数组

数组一样也是被支持的,如下:

bash 复制代码
db.sang_collec.insert({x:[1,2,3,4,new Date()]})

数组中的数据类型可以是多种多样的。

日期

MongoDB支持Date类型的数据,可以直接new一个Date对象,如下:

bash 复制代码
db.sang_collec.insert({x:new Date()})

内嵌文档

一个文档也可以作为另一个文档的value,这个其实很好理解,如下:

bash 复制代码
db.sang_collect.insert({name:"三国演义",author:{name:"罗贯中",age:99}});

书有一个属性是作者,作者又有name,年龄等属性。

四、MongoDB 中的索引

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。

索引创建

默认情况下,集合中的_id字段就是索引,我们可以通过getIndexes()方法来查看一个集合中的索引:

bash 复制代码
db.aaa.getIndexes()

现在我的集合中有10000个文档,我想要查询x1的文档,我的查询操作如下:

bash 复制代码
db.sang_collect.find({x:1})

这种查询默认情况下会做全表扫描,我们可以用上篇文章介绍的explain()来查看一下查询计划,如下:

bash 复制代码
db.sang_collect.find({x:1}).explain("executionStats")

bash 复制代码
> db.集合名称.createIndex(keys, options)
> db.集合名称.createIndex({"title":1,"description":-1})

说明: 语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

一个索引的值是由多个 key 进行维护的索引的称之为复合索引

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

查看索引

getIndexes()可以用来查看索引,我们还可以通过totalIndexSize()来查看索引的大小,如下:

db.sang_collect.totalIndexSize()

删除索引

我们可以按名称删除索引,如下:

db.sang_collect.dropIndex("xIndex")

表示删除一个名为xIndex的索引,当然我们也可以删除所有索引,如下:

db.sang_collect.dropIndexes()

总结

索引是个好东西,可以有效的提高查询速度,但是索引会降低插入、更新和删除的速度,因为这些操作不仅要更新文档,还要更新索引,MongoDB 限制每个集合上最多有64个索引,我们在创建索引时要仔细斟酌索引的字段。

相关推荐
指尖上跳动的旋律1 小时前
shell脚本定义特殊字符导致执行mysql文件错误的问题
数据库·mysql
一勺菠萝丶1 小时前
MongoDB 常用操作指南(Docker 环境下)
数据库·mongodb·docker
m0_748244832 小时前
StarRocks 排查单副本表
大数据·数据库·python
C++忠实粉丝2 小时前
Redis 介绍和安装
数据库·redis·缓存
wmd131643067122 小时前
将微信配置信息存到数据库并进行调用
数据库·微信
是阿建吖!3 小时前
【Linux】基础IO(磁盘文件)
linux·服务器·数据库
凡人的AI工具箱3 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
ClouGence3 小时前
Redis 到 Redis 数据迁移同步
数据库·redis·缓存
m0_748236583 小时前
《Web 应用项目开发:从构思到上线的全过程》
服务器·前端·数据库
苏三说技术3 小时前
Redis 性能优化的18招
数据库·redis·性能优化