0.1. 基础概念
0.1.1. 数据库
数据库是集合和其相关索引的命名空间,同时也是他们的物理聚合。
查看数据库文件夹,可以发现大部分文件名是以 collection 或者 index 开头的。(WiredTiger)
0.1.2. 集合
集合是结构或概念上相似文档的容器。
集合是通过命名空间中的名字来进行识别的,通常名字中含有所在数据库的数据库名。 如:
garden.products
.
通过创建集合的方法了解集合:
db.createCollection(<name>, { capped: <boolean>,
size: <number>,
max: <number>,
storageEngine: <document>,
validator: <document>,
validationLevel: <string>,
validationAction: <string>,
indexOptionDefaults: <document>,
viewOn: <string>,
pipeline: <pipeline>,
collation: <document> } )
capped: 如果 true 则创建盖子集合。(具有上限的集合,可实现队列式操作)
size:为盖子集合设置大小。
max:盖子集合的最大文档数,优先级低于 size
。
storageEngine:存储引擎,默认是 WiredTiger 。
0.1.3. 视图
在 mongoDB 3.4 中新加入了视图概念, 它可以看成是一种特殊的集合。
视图是由已有集合或视图创建的一种只读集合。
上述创建集合的方法也可以创建视图:
viewOn: 已有集合或视图的名字,不包含数据库名。
pipeline:通过管道来进行聚合操作。
0.2. Shell 操作 MongoDB
MongoDB 3.4 学习笔记 (一): Win10 安装 MongoDB Community 3.4
接上次的教程,此教程假设已建立了全局的用户管理员(userAdminAnyDatabase): "myUserAdmin"
0.2.1. 启动 shell
-
首先确定 windows 服务已开启
$ net start MongoDB
-
启动 shell
$ mongo MongoDB shell version v3.4.3 connecting to: mongodb://127.0.0.1:27017/ MongoDB server version: 3.4.3 >
0.2.2. 建立相关授权用户
-
切换到授权数据库
> use admin ...... > db.auth("myUserAdmin", "abc123" )
-
创建 tutorial 数据库并建立相应的用户(这里建立的是 tutorial 数据库拥有者的角色)
> use tutorial ...... > db.createUser( { user: "myTester", pwd: "xyz123", roles: [ { role: "dbOwner", db: "tutorial" } , { role: "readWrite", db:"test"} ] })
切换到 myTester 用户:
> db.auth("myTester", "xyz123")
创建用户时可同时为用户建立多个数据库对应的角色。
0.2.3. 插入和查询文档
命令 | 功能 |
---|---|
db.collection.insertOne() | 插入一个单独的文档到集合 |
db.collection.insertMany() | 插入多个文档到集合 |
db.collection.insert() | 插入一个或多个文档到集合 |
db.collection.find() | 查询命令 |
-
向 users 集合插入一个文档:
> db.users.insert({ username: "smith"}) WriteResult({ "nInserted" : 1 })
-
查看新文档数据:
> db.users.find() { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith" }
-
条件查询:
首先插入一个新的文档:
> db.users.insert({ username: "jones"}) WriteResult({ "nInserted" : 1 }) > db.users.find() { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith" } { "_id" : ObjectId("5915a73a7f93ecc782f7a4b8"), "username" : "jones" }
然后单独查询集合中 username 为 jones 的文档:
> db.users.find({username: "jones"}) { "_id" : ObjectId("5915a73a7f93ecc782f7a4b8"), "username" : "jones" }
最后使用操作符进行条件查询:
> db.users.find({ $or: [ ... {username: "smith"}, ... {username: "jones"} ... ]}) { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith" } { "_id" : ObjectId("5915a73a7f93ecc782f7a4b8"), "username" : "jones" }
在查询操作中,我们使用文档作为查询条件,这与关系型数据库差别很大。
0.2.4. 更新文档
命令 | 功能 |
---|---|
db.collection.updateOne() | 更新一个文档即使有多个文档匹配 |
db.collection.updateMany() | 更新所有匹配的文档 |
db.collection.replaceOne() | 替换一个文档即使有多个文档匹配 |
db.collection.update() | 通用更新替换命令 |
-
更新操作符(
$set
)$set
操作符通常用来为单个字段设置特定的值。> db.users.update({ username: "smith"}, {$set: {country: "Canada"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find({username: "smith"}) { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith", "country" : "Canada" }
-
替换更新
当把
$set
取消后,更新的效果即变成了替换效果:> db.users.update({username: "smith"}, {country: "Canada"}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find({country: "Canada"}) { "_id" : ObjectId("591572f1a6400b211256d028"), "country" : "Canada" }
注意: 当确认是新增或修改字段而不是替换字段时,请使用
$set
操作符。练习:还原初始文档
> db.users.update({country: "Canada"}, {$set: {username: "smith"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.update({username: "smith"}, {$unset: {country: 1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find({username: "smith"}) { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith" }
-
复杂数据更新
为两个文档添加喜欢的电影和城市:
> db.users.update( {username: "smith"}, ... { ... $set: { ... favorites: { ... cities: ["Chicago", "Rolla"], ... movies: ["Casablanca, "Moon River", "Transporting"] ... } ... } ... }) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.update( {username: "jones"}, ... { ... $set: { ... favorites: { ... movies: ["Casablanca", "Rocky"] ... } ... } ... }) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
查看文档的良好格式:
> db.users.find().pretty() { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith", "favorites" : { "cities" : [ "Chicago", "Rolla" ], "movies" : [ "Casablanca", "Moon River", "Transporting" ] } } { "_id" : ObjectId("5915a73a7f93ecc782f7a4b8"), "username" : "jones", "favorites" : { "movies" : [ "Casablanca", "Rocky" ] } }
查询喜欢《卡萨布兰卡》的文档:
> db.users.find({"favorites.movies": "Casablanca"}) { "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith", "favorites" : { "cities" : [ "Chicago", "Rolla" ], "movies" : [ "Casablanca", "Moon River", "Transporting" ] } } { "_id" : ObjectId("5915a73a7f93ecc782f7a4b8"), "username" : "jones", "favorites" : { "movies" : [ "Casablanca", "Rocky" ] } }
注意: 查询键名加上了引号。
高级更新
更新命令定义的详细格式:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>
}
)
upsert
(update & insert): 默认 false ,如果设为 true 则当没有匹配文档即建立一个新文档。
multi
: 默认 false, 如果设为 true 则可更新多个匹配文档。
此外除了 $set
操作符外,还经常使用 $push
和 $addToSet
操作符 。
> db.users.update({"favorites.movies": "Casablanca"},
... {$push: {"favorites.movies": "Frozen"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find().pretty()
{
"_id" : ObjectId("591572f1a6400b211256d028"),
"username" : "smith",
"favorites" : {
"cities" : [
"Chicago",
"Rolla"
],
"movies" : [
"Casablanca",
"Moon River",
"Transporting",
"Frozen"
]
}
}
{
"_id" : ObjectId("5915a73a7f93ecc782f7a4b8"),
"username" : "jones",
"favorites" : {
"movies" : [
"Casablanca",
"Rocky"
]
}
}
0.2.5. 删除数据
命令 | 功能 |
---|---|
db.collection.deleteOne() | 删除一个文档即使有多个文档匹配 |
db.collection.deleteMany() | 删除所有匹配的文档 |
db.collection.remove() | 通用删除命令 |
- 删除文档
> db.users.remove({"favorites.movies": "Rocky"})
WriteResult({ "nRemoved" : 1 })
> db.users.find()
{ "_id" : ObjectId("591572f1a6400b211256d028"), "username" : "smith", "favorites" : { "cities" : [ "Chicago", "Rolla" ], "movies" : [ "Casablanca", "Moon River", "Transporting", "Frozen" ] } }
- 删除集合
> db.users.drop()
true
> show collections