1. 背景
本节使用命令行操作 mongDB。
2.知识
MongoDB是一个文档型数据库,它将数据存储在类似json的文档中。
特点:
- 数据以JSON方式存储,处理数据最自然,支持数组和嵌套对象。
- 查询也以JSON方式,支持筛选和排序,聚合。
和 关系型数据的概念对照表:
MongoDB | 传统的关系型数据库 |
---|---|
database | database, 相同 |
collections | table |
documents | row |
fields | columns |
Indexes | Indexes 相同 |
Cursors | - |
总结:MongoDB 可以每行数据的结构都不同,支持非结构化数据。 区别于 传统的严格结构化数据。
MongoDB 适用场景
单一解决方案还是多技术方案?
对于许多项目来说 - 或者说大多数 - 单一解决案是一个明智的选择。只有你自己才知道,引进新技术是否利大于弊。引入MongoDB 往往不会完全替换旧的方案(比如用Mongo替换MySQL),而是说“不用再依赖单一的解决案来处理你的数据”,作为数据存储的局部替代方案,是对你现有数据存储方案能力的局部增强。
比如说用 Lucene 作为关系型数据库的全文检索索引的加强,或者用 Redis 作为持久型 key-value 存储对缓存存储的增强,MongoDB 就是用来保存你的数据能力的处理增强。
3. 使用 Docker 安装 mongoDB
(1) 安装 mongoDB
我使用 docker 安装,编写一个 docker-compose.yml 文件:
version: '3.1'
services:
mongo:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
(2) 启动docker容器
在当前文件夹下执行:
docker compose up -d
(3) 进入容器 内
docker exec -it mongodb_mongo_1 /bin/bash
(4) 进入 mongodb 的命令行交互界面
执行:
mongo
或者 指定用户名和密码登录:
mongo --host localhost --authenticationDatabase "admin" -u "root" -p'123456'
也可使用其他客户端工具,比如 navcat for mongoDB
下面展示一些使用 mongoShell 的示例。
4. 基本操作
进入命令行后就可以使用 mongodb 的语句了, 比如 输入 db.version() 查看mongoDB 的版本号。
查看版本号
执行: db.version()
> db.version()
4.2.5
记得按下 tab 键帮忙快速输入
使用
查看有哪些数据库
执行:show dbs
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
切换数据库:
执行:use 数据库名
> use admin
查看这个数据库下有哪些用户
执行:: show users
> show users
{
"_id" : "admin.root",
"userId" : UUID("997d937e-d05f-4df0-b233-e3f549e25bbc"),
"user" : "root",
"db" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
查看当前数据库的状态
执行:: db.stats()
> db.stats()
{
"db" : "admin",
"collections" : 2,
"views" : 0,
"objects" : 3,
"avgObjSize" : 208.66666666666666,
"dataSize" : 626,
"storageSize" : 40960,
"numExtents" : 0,
"indexes" : 3,
"indexSize" : 61440,
"scaleFactor" : 1,
"fsUsedSize" : 28565065728,
"fsTotalSize" : 62725623808,
"ok" : 1
}
要显示您正在使用的数据库,请键入db:
db
创建新的数据库
先切换到不存在的数据库。通过创建集合时,MongoDB会创建数据库。
比如我要建一个名字叫做 new_db 的库,示例:
> use new_db
switched to db new_db
> db.table1.insertOne({x:1})
{
"acknowledged" : true,
"insertedId" : ObjectId("60f6e7ad60d17362b807365e")
}
一个名叫 "table1" 的 collection 就被创建了。
然后查看一下 刚刚建的 Collection :
> db.table1.find()
{ "_id" : ObjectId("60f6e7ad60d17362b807365e"), "x" : 1 }
5. 基本的增删改查 CRUD
插入 数据
格式:
db.collection.insertOne() 3.2版中的新功能
db.collection.insertMany() 3.2版中的新功能
“ collection ” 换成你实际的 “表” 名。
示例:
> db.table1.insertOne({name:"zyfvir"})
{
"acknowledged" : true,
"insertedId" : ObjectId("60f6e8fe60d17362b807365f")
}
一次插入多条数据
使用 insertMany 方法:
db.inventory.insertMany( [
{ item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },
{ item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },
{ item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },
{ item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
下文的一些查询要用到这个结构的文档,它还有size ,instock 两个嵌入的子文档。
读取 collection
格式:db.collection.find()
示例:
> db.table1.find({})
{ "_id" : ObjectId("60f6e7ad60d17362b807365e"), "x" : 1 }
{ "_id" : ObjectId("60f6e8fe60d17362b807365f"), "name" : "zyfvir" }
删除一条数据
> db.table1.deleteOne({"x":1})
{ "acknowledged" : true, "deletedCount" : 1 }
删除数据
> db.table1.remove({"name" : "zyfvir"})
WriteResult({ "nRemoved" : 1 })
查询全部
> db.inventory.find()
指定条件的查询
下面的例子返回inventory集合中状态为“A”的所有文档中的所有字段:
db.inventory.find( { status: "A" } )
该操作对应于以下SQL语句:
SELECT * from inventory WHERE status = "A"
仅返回指定的字段和_id字段
> db.inventory.find( { status: "A" }, { item: 1, status: 1 } )
{ "_id" : ObjectId("60f6f27960d17362b8073660"), "item" : "journal", "status" : "A" }
{ "_id" : ObjectId("60f6f27960d17362b8073661"), "item" : "notebook", "status" : "A" }
{ "_id" : ObjectId("60f6f27960d17362b8073664"), "item" : "postcard", "status" : "A" }
明确表达某个字段不显示
比如:不显示_id 字段
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
查询展示 嵌入式文档中的特定字段
db.inventory.find(
{ },
{ "size.uom": 1 }
)
说明:用 逗号 操作符 size.uom 这样的格式表达子嵌入文档。
查询空字段
先插入示例数据:
db.inventory.insertMany([
{ _id: 1, item: null },
{ _id: 2 }
])
查询匹配包含值是null:
格式:{item:null}
查询匹配包含值是null的item字段或不包含item字段的文档。
db.inventory.find( { item: null } )
类型检查
格式:{item:{$ type:10}}
查询只匹配包含item字段值为null的文档; 即item字段的值为Null(类型编号10):
db.inventory.find( { item : { $type: 10 } } )
更多类型参考:BSON Type
指定AND条件
逗号分隔即可:
以下查询选择嵌套字段h小于15,嵌套字段uom等于“ in”,状态字段等于“ D”的所有文档:
db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )
更新集合中的文档
使用 $set
示例:
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
}
)
更新操作:
使用$set
运算符将size.uom字段的值更新为“ cm”,将状态字段的值更新为“ P”,
使用$currentDate
运算符将lastModified字段的值更新为当前日期。 如果lastModified字段不存在,则$currentDate
将创建该字段。 有关详细信息,请参见$currentDate
。
更换文档
要替换_id字段以外的文档的全部内容,请将一个全新的文档作为第二个参数传递给db.collection.replaceOne()。
db.inventory.replaceOne(
{ item: "paper" },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)
5. 索引
索引支持在MongoDB中有效地执行查询。如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,
默认id索引
在创建集合期间,MongoDB 在_id字段上创建唯一索引。
创建索引
要在Mongo Shell中创建索引 ,请使用 db.collection.createIndex().
以下示例在name字段上创建单个键降序索引:
db.collection.createIndex( { name: -1 } )
复合索引
MongoDB还支持多个字段上的用户定义索引,即 复合索引。
6.参考:
想了解更多 docker 部署 mongoDB 请参考:
https://hub.docker.com/_/mongo?tab=description&page=1&ordering=last_updated
https://github.com/docker/compose
https://docs.mongoing.com/indexes
END