文章目录
- 一、数据库操作
- 二、集合操作
- 三、文档操作
- 3.1 插入文档
- 3.2 查询文档
- 3.3 更新文档
- 3.4 删除文档
- 四、安全认证
- 4.1 创建管理员账号
- 4.2 创建应用数据库用户
- 4.3 启动和连接 (校验方式)
提示:以下是本篇文章正文内容,MongoDB 系列学习将会持续更新
一、数据库操作
①查看数据库
show dbs
show databases
②查看当前正在使用的数据库 (默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中)
db
③选择或创建数据库 (新建的数据库会暂时存放到内存中,所以无法用show查看,只有插入内容会才会持久化到磁盘中)
use 数据库名称
④删除数据库
db.dropDatabase()
⑤默认存在的数据库
- admin:从权限的角度来看,这是 “root” 数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local:这里的数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
- config:当 Mongo 用于分片设置时,config 数据库在内部使用,用于保存分片的相关信息。
二、集合操作
①查看集合
show collections
show tables
②显式创建集合
db.createCollection(集合名)
db.createCollection("books")
# 设置参数
db.createCollection(name, options)
固定集合 options 参数:
字段 | 类型 | 描述 |
---|---|---|
capped | 布尔 | (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 |
size | 数值 | (可选)为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也需要指定该字段。 |
max | 数值 | (可选)指定固定集合中包含文档的最大数量。 |
③删除集合:结果会返回 true 或 false
db.collection.drop()
db.books.drop()
④查看集合详情
db.collection.stats()
回到目录…
三、文档操作
文档(document)的数据结构和 JSON 基本一样,所有存储在集合中的数据都是 BSON 格式。
3.1 插入文档
insert
:若插入的数据主键已经存在,则会抛 DuplicateKeyException 异常,提示主键重复,不保存当前数据。支持单行和多行插入save
:如果 _id 主键存在则更新数据,如果不存在就插入数据。支持单行和多行插入db.collection.insertOne()
:版本3.2新增,支持 writeConcern。仅支持单行插入db.collection.insertMany()
:版本3.2新增,支持 writeConcern。支持多行插入
writeConcern 决定一个写操作落到多少个节点上才算成功。它的取值包括:
0
:发起写操作,不关心是否成功。1
:默认的写入策略。集群最大数据节点数,写操作需要被复制到指定节点数才算成功。majority
:写操作需要被复制到大多数节点上才算成功。
①新增单个文档
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
db.user.insertOne({name:"zhangsan",password:"123",age:18})
②批量新增文档: ordered 指定是否按顺序写入,默认 true,按顺序写入。
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
db.user.insertMany([{name:"lisi",password:"456",age:19},{name:"wangwu",password:"789",age:20},{name:"zhaoliu",password:"258",age:21}])
③执行脚本插入
编辑脚本 book.js
var tags = ["nosql","mongodb","document","developer","popular"];
var types = ["technology","sociality","travel","novel","literature"];
var books=[];
for(var i=0;i<50;i++){
var typeIdx = Math.floor(Math.random()*types.length);
var tagIdx = Math.floor(Math.random()*tags.length);
var favCount = Math.floor(Math.random()*100);
var book = {
title: "book-"+i,
type: types[typeIdx],
tag: tags[tagIdx],
favCount: favCount,
author: "xxx"+i
};
books.push(book)
}
db.book.insertMany(books);
进入 MongoShell 中执行:pwd() 查看当前路径
load("../js/books.js")
回到目录…
3.2 查询文档
db.collection.find(query, projection)
db.collection.findOne(query, projection)
- query:可选,使用查询操作符指定查询条件。
- projection:可选,使用投影操作符指定返回的键。投影时,id为1的时候,其他字段必须是1;id是0的时候,其他字段可以是0;如果没有_id字段约束,多个其他字段必须同为0或同为1。
①指定文档查询
# 全列查询
db.book.find()
// 指定列查询,(0表示不查、1表示查询), 默认_id:1
db.book.find({},{title:1,author:1})
// 仅查询 title 和 author 字段
db.book.find({},{_id:0,title:1,author:1})
②条件查询
// 查询标题为“book-2”的文档
db.book.find({title:"book-2"})
// 查询分类为“travel” 且 收藏数超过60个的book文档
db.book.find({type:"travel",favCount:{$gt:60}})
// 查询type为“travel” 或 tag为"nosql"的book文档
db.book.find({$or:[{type:"travel"},{tag:"nosql"}]})
示例:
逻辑运算符对照表:
逻辑运算符 | SQL | MQL |
---|---|---|
a = 1 | {a: 1} | |
$lt | a < 1 | {a: {$lt: 1}} |
$lte | a <= 1 | {a: {$lte: 1}} |
$gt | a > 1 | {a: {$gt: 1}} |
$gte | a >= 1 | {a: {$gte: 1}} |
$ne | a != 1 | {a: {$ne: 1}} |
$and | a = 1 and b = 1 | {a: 1, b: 1} 或 {$and: [{a: 1}, {b: 1}]} |
$in | a in (1, 2, 3) | {a: {$in: [1, 2, 3]}} |
$nin | a not in (1, 2, 3) | {a: {$nin: [1, 2, 3]}} |
$or | a = 1 or b = 1 | {$or: [{a: 1}, {b: 1}]} |
$regex | c 包含字符串 “abc” | {c: {$regex: “abc”}} |
③排序 & 分页
指定排序:使用 sort() 方法对数据进行排序。
// 指定按收藏数(favCount)降序返回
db.book.find().sort({favCount:-1})
分页查询:skip 用于指定跳过记录数,limit 则用于返回结果数量。
// 分页设计: 每页大小为8条的book文档
// 第一页
db.book.find().skip(0).limit(8)
// 第二页
db.book.find().skip(8).limit(8)
// 第三页
db.book.find().skip(16).limit(8)
④正则表达式匹配查询
// 查找type包含“so”字符串的book文档
db.book.find({type:{$regex:"so"}})
// 使用正则表达式
db.book.find({type:/so/})
回到目录…
3.3 更新文档
db.collection.update(query,update,options)
- query:描述更新的查询条件。
- update:描述更新的动作及新的内容。
- options:描述更新的选项。
upsert
: 可选,如果不存在 update 的记录,是否插入新的记录。默认 false,不插入。multi
: 可选,是否按条件查询出的多条记录全部更新。 默认 false,只更新找到的第一条记录。writeConcern
:可选,决定一个写操作落到多少个节点上才算成功。
操作符 | 格式 | 描述 |
---|---|---|
$set | {$set:{field:value}} | 指定一个键并更新值,若键不存在则创建 |
$unset | {$unset : {field : 1 }} | 删除一个键 |
$inc | {$inc : {field : value } } | 对数值类型进行增减 |
$rename | {$rename : {old_field_name : new_field_name } } | 修改字段名称 |
$push | { $push : {field : value } } | 将数值追加到数组中,若数组不存在则会进行初始化 |
$pushAll | {$pushAll : {field : value_array }} | 追加多个值到一个数组字段内 |
$pull | {$pull : {field : _value } } | 从数组中删除指定的元素 |
$addToSet | {$addToSet : {field : value } } | 添加元素到数组中,具有排重功能 |
$pop | {$pop : {field : 1 }} | 删除数组的第一个或最后一个元素 |
①更新单个文档
// 将book-0书籍的数量增加一本
db.book.update({title:"book-0"},{$inc:{favCount:1}})
②更新多个文档
// 将分类为“novel”的文档的增加发布时间(publishedDate)
db.book.update({type:"novel"},{$set:{publisherDate:new Date()}},{multi:true})
update 命令的选项配置较多,为了简化使用还可以使用一些快捷命令:
- updateOne:更新单个文档。
- updateMany:更新多个文档。
- replaceOne:替换单个文档。
③使用 upsert 命令: 如果目标文档不存在,则执行插入命令。
db.book.update(
{title:"myBook"},
{$set:{tags:["nosql","mongodb"],type:"none",author:"fox"}},
{upsert:true})
nMatched、nModified 都为0,表示没有文档被匹配及更新,nUpserted=1提示执行了upsert动作。
④实现 replace 语义: 如果更新描述中不包含任何操作符,就会实现 replace 替换。
db.book.update(
{title:"myBook"},
{mytitle:"newBook"})
⑤findAndModify 命令
findAndModify 兼容了查询和修改指定文档的功能,findAndModify 只能更新单个文档。
// 将某个book文档的收藏数(favCount)加1
db.book.findAndModify({
query:{title:"book-0"},
update:{$inc:{favCount:1}}
})
该操作会返回修改前的 “旧” 数据,并完成对文档的修改。
// 可以指定 new 选项,返回修改后的 “新” 数据。
db.book.findAndModify({
query:{title:"book-0"},
update:{$inc:{favCount:1}},
new:true
})
与 findAndModify 语义相近的命令如下:
- findOneAndUpdate:更新单个文档并返回更新前(或更新后)的文档。
- findOneAndReplace:替换单个文档并返回替换前(或替换后)的文档。
回到目录…
3.4 删除文档
①使用 remove 删除
- remove 命令需要配合查询条件使用;
- 匹配查询条件的文档会被删除;
- 指定一个空文档条件会删除所有文档;
db.book.remove({title:"book-5"}) //删除某个标题的书籍
db.book.remove({favCount:{$lt:30}}) //删除数量少于30的书籍
db.book.remove({}) //删除所有记录
db.book.remove() //报错
remove 命令会删除匹配条件的全部文档,如果希望明确限定只删除一个文档,则需要指定 justOne 参数,命令格式如下:
db.collection.remove(query,justOne)
// 示例: 删除满足type:novel条件的首条记录
db.book.remove({type:"novel"},true)
②使用 delete 删除 (官方推荐)
db.book.deleteMany({}) //删除集合下全部文档
db.book.deleteMany({type:"novel"}) //删除 type等于 novel 的全部文档
db.book.deleteOne({type:"travel"}) //删除 type等于 travel 的一个文档
③返回被删除文档
如果希望获得被删除的文档,可以使用 findOneAndDelete,但只能删除并返回第一条结果:
db.books.findOneAndDelete({type:"novel"})
除了在结果中返回删除文档,还允许定义“删除的顺序”,即按照指定顺序删除找到的第一个文档:
db.books.findOneAndDelete({type:"novel"},{sort:{favCount:1}})
回到目录…
四、安全认证
4.1 创建管理员账号
# 设置管理员用户名密码需要切换到admin库
use admin
# 创建管理员
db.createUser({user:"root",pwd:"123456",roles:["root"]})
# 查看所有用户信息
show users
# 删除用户
db.dropUser("root")
4.2 创建应用数据库用户
use library
db.createUser({user:"wsy",pwd:"123456",roles:["dbOwner"]})
常用角色权限:
权限名 | 描述 |
---|---|
read | 允许用户读取指定数据库 |
readWrite | 允许用户读写指定数据库 |
dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
dbOwner | 允许用户在指定数据库中执行任意操作,增、删、改、查等 |
userAdmin | 允许用户向system.users集合写入,可以在指定数据库里创建、删除和管理用户 |
clusterAdmin | 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限 |
readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
dbAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限 |
root | 只在admin数据库中可用。超级账号,超级权限 |
4.3 启动和连接 (校验方式)
①默认情况下,MongoDB 不会启用鉴权,以鉴权模式启动 MongoDB
mongod -f ../conf/mongod.conf --auth
②启用鉴权之后,连接 MongoDB 的相关操作都需要提供身份认证
mongo -u用户名 -p密码 --authenticationDatabase=用户所在库
mongo -uroot -p123456 --authenticationDatabase=admin
mongo -uwsy -p123456 --authenticationDatabase=library
管理员可以看到并操作所有数据库:
普通用户只能看到并操作对应的数据库:
回到目录…
总结:
提示:这里对文章进行总结:
本文是对MongoDB的学习,学习了针对数据库、集合、文档的增删查改操作,并且学习创建用户及权限、以安全认证的方式启动MongoDB。之后的学习内容将持续更新!!!