简介
MongoDB 是免费开源的跨平台 NoSQL 数据库,命名源于英文单词 humongous,意思是「巨大无比」,可见开发组对 MongoDB 的定位。与关系型数据库不同,MongoDB 的数据以类似于 JSON 格式的二进制文档存储。
NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。指的是非关系型的数据库,是对不同于传统的关系型数据库的数据库管理系统的统称。NoSQL用于超大规模数据的存储。
文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。文档不对数据结构加以限制,不同的数据结构可以存储在同一张表。
开始
安装
这里采用 docker 拉取的方式,该镜像的详细使用说明请见官方文档 。
其他安装方式,见官网。
docker pull mongo
配置
docker方式的启动:
docker run -d --name mongo \
--network web \
-p 27017:27017 \
-v /Users/666/Documents/exercise/N-blog/data/db:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=mongoadmin \
-e MONGO_INITDB_ROOT_PASSWORD=secret \
mongo
其他方法见说明文档。
连接
mongo [options] [db address] [file names (ending in .js)]
db address can be:
foo foo database on local machine
192.168.0.5/foo foo database on 192.168.0.5 machine
192.168.0.5:9999/foo foo database on 192.168.0.5 machine on port 9999
mongodb://192.168.0.5:9999/foo connection string URI can also be used
# 访问示例:
mongo -u mongoadmin -p secret --authenticationDatabase admin 127.0.0.1:12345
以上是命令行的操作,而docker容器是提供了shell访问的:
docker exec -it mongo bash
我们也可以安装 mongodb-compass-community,进行连接:
brew cask install mongodb-compass-community
操作
看一下最基本的 CRUD 操作,这之前熟悉一下常用的 shell 操作:
db显示当前所在数据库,默认为 testshow dbs列出可用数据库show tablesshow collections列出数据库中可用集合use <database>用于切换数据库
由于 该 docker 镜像提供 shell 访问,于是可以愉快的玩耍:
docker exec -it mongo bash # 提供 shell 访问
可以 use 一个不存在的数据库,当你存入新数据时,mongoDB 会创建这个数据库。
本小节具体可以查看官方文档。
命令示例:
mongo -u mongoadmin -p secret --authenticationDatabase admin 127.0.0.1:27017
root@98107395f2ca:/# mongo -u mongoadmin -p secret --authenticationDatabase admin 127.0.0.1:27017
MongoDB shell version v4.2.0
connecting to: mongodb://127.0.0.1:27017/test?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d3496ab6-1e07-4810-88e2-2ba7542873c2") }
MongoDB server version: 4.2.0
>
> db
test
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
> use admin
switched to db admin
> show tables
system.users
system.version
> show collections
system.users
system.version
>
mongoDB 预设有两个数据库,admin 和 local,admin 用来存放系统数据,local 用来存放该实例数据,在副本集中,一个实例的 local 数据库对于其它实例是不可见的。
可以 use 一个不存在的数据库,当你存入新数据时,mongoDB 会创建这个数据库。
CRUD
文档简介
CRUD操作可创建,读取,更新和删除文档(DOCUMENT)。
var mydoc = {
_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" },
birth: new Date('Jun 23, 1912'),
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}
BSON 类型
MongoDB将数据记录存储为BSON文档。BSON是JSON文档的二进制表示形式,尽管它包含比JSON更多的数据类型。有关BSON规范,请参见bsonspec.org。
MongoDB文档由字段(字段名称是字符串)和值对组成,字段的值可以是任何BSON数据类型,包括其他文档,数组和文档数组。
BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型。
BSON文档的最大大小为16 MB。
ObjectId:很小,很可能是唯一的,可以快速生成并排序。ObjectId值由12个字节组成,前四个字节是反映ObjectId创建的时间戳,时间戳是自1970 年1 月1 日(00:00:00 GMT)以来的秒数,5个字节的随机值,以及一个3字节的计数器。在MongoDB中,存储在集合中的每个文档都需要一个唯一的_id字段作为主键。如果插入的文档忽略该_id字段,则MongoDB驱动程序会自动为该字段生成一个ObjectId_id。String:字符串为UTF-8。Timestamps:BSON有一个特殊的时间戳类型内部MongoDB的使用,前32位是一个time_t值(自Unix时代以来的秒数),后32位是ordinal给定秒内操作的增量。Date:是一个64位整数,代表自Unix纪元(1970年1月1日)以来的毫秒数。这导致过去和将来的可表示日期范围约为2.9亿年。负值表示1970年之前的日期。
MongoDB使用点表示法来访问数组的元素并访问嵌入式文档的字段。
- 要通过从零开始的索引位置指定或访问数组的元素,请将数组名称与点(.)和从零开始的索引位置连接起来,并用引号引起来:
“<数组>.<索引>”。例如要指定contribs数组中的第三个元素,请使用点符号"contribs.2"。 - 要使用点符号指定或访问嵌入式文档的字段,请将嵌入式文档名称与点(.)和字段名称连接在一起,并用引号引起来:
“<嵌入的文档>.<字段>”。例如要获取在name字段中last的字段,请使用点符号"name.last"。
CRUD 操作
创建 create
MongoDB 提供 insert 方法创建新文档:
db.collection.inserOne()插入单个文档db.collection.inserMany()插入多个文档db.collection.insert()插入单条或多条文档
> db.test.insert({name: "Yuhan", age: 21})
WriteResult({ "nInserted" : 1 })
> db.test.find()
{ "_id" : ObjectId("5d9bfbb17bee691528be1aa7"), "name" : "Yuhan", "age" : 21 }
>
插入新文档如果未指定 _id,mongoDB 会自动为插入的文档添加 _id 字段。使用 db.dirvers.find() 命令即可看到刚刚插入的文档。
查找 read
MongoDB 提供 find 方法查找文档,第一个参数为查询条件,第二个参数可以传入投影:
> db.test.find({age:{$gt:30}}, {name:1})
{ "_id" : ObjectId("5d9d9c3faae33bd836c27bd8"), "name" : "Nihao" }
投影文档中字段为 1 或真值表示包含,0 或假值表示排除,可以设置多个字段为 1 或 0,但不能混合使用。
除此之外,还可以通过 count、skip、limit 等指针(Cursor)方法,改变文档查询的执行方式:
> db.test.find().skip(1).limit(10).sort({age:1})
{ "_id" : ObjectId("5d9d9bf0aae33bd836c27bd7"), "name" : "Yuhan", "age" : 21 }
{ "_id" : ObjectId("5d9d9c3faae33bd836c27bd8"), "name" : "Nihao", "age" : 88 }
跳过 1 个文档,限制输出 10 个,以 name 子段正序排序(大于 0 为正序,小于 0 位反序)输出结果。可以使用 Cursor 方法中的 pretty 方法,提升查询文档的易读性:
> db.test.find().skip(1).limit(10).sort({age:1}).pretty()
{
"_id" : ObjectId("5d9d9bf0aae33bd836c27bd7"),
"name" : "Yuhan",
"age" : 21
}
{
"_id" : ObjectId("5d9d9c3faae33bd836c27bd8"),
"name" : "Nihao",
"age" : 88
}
更新 update
MongoDB 提供 updata 方法更新文档:
db.collection.updateOne()更新最多一个符合条件的文档db.collection.updateMany()更新所有符合条件的文档db.collection.replaceOne()替代最多一个符合条件的文档db.collection.update()默认更新一个文档,可配置multi参数,更新多个文档
格式:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>
}
)
# 示例,$set 指令仅替换或增加指定字段
> db.test.update({age:21},{$set:{name:"YH"}},{multi:true})
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
> db.test.find()
{ "_id" : ObjectId("5d9bfbb17bee691528be1aa7"), "name" : "YH", "age" : 21 }
{ "_id" : ObjectId("5d9d9bf0aae33bd836c27bd7"), "name" : "YH", "age" : 21 }
{ "_id" : ObjectId("5d9d9c3faae33bd836c27bd8"), "name" : "Nihao", "age" : 88 }
删除 delete
MongoDB 提供了 delete 方法删除文档:
db.collection.deleteOne()删除最多一个符合条件的文档db.collection.deleteMany()删除所有符合条件的文档db.collection.remove()删除一个或多个文档,可配置justOne参数,仅删除匹配的第一个
MongoDB 提供了 drop 方法删除集合,返回 true 表面删除集合成功。
> db.test.remove({age:21},{justOne:true})
WriteResult({ "nRemoved" : 1 })
> db.test.find()
{ "_id" : ObjectId("5d9d9bf0aae33bd836c27bd7"), "name" : "YH", "age" : 21 }
{ "_id" : ObjectId("5d9d9c3faae33bd836c27bd8"), "name" : "Nihao", "age" : 88 }
结语
相比传统的关系数据库查询和操纵语言,MongoDB的CRUD操作更像编写程序,更符合开发人员的直觉,但它也支持 SQL 语言。一句话就是:还有很长路要走。
dfface 的版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处,严禁商业用途!