一. windows启动mongodb
- 服务端启动
mongod.exe --dbpath ../data --logpath ../log/mongodb.log --port 27017
- 客户端启动
mongo.exe --port=27017
二. 数据库操作
show dbs; show databases; # 查看所有库
use test # 切换到指定数据库,不存在则创建
db # 查看当前所在的库
db.dropDatabase() # 删除当前数据库
三. 集合操作
mongodb里的集合,相当于mysql里的表。
show tables; show collections # 两个都是查看集合
db.createCollection("emp") # 显式创建集合;插入行数据就相当于隐式创建集合
db.users.drop() # 删除集合
显式创建集合语法: db.createCollection(name, options)
options参数
字段 | 类型 | 描述 |
---|---|---|
capped | 布尔 | (可选)如果为true,则创建固定集合。固定集合是指有着固定大小的集合, |
当达到最大值时,它会自动覆盖最早的文档。 | ||
size | 数值 | (可选)为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也 |
需要指定该字段。 | ||
max | 数值 | (可选)指定固定集合中包含文档的最大数量。 |
四. 文档操作
mongodb里的文档,相当于mysql里的行记录。
-
插入文档
- 命令行插入:
db.collection.insert(<document>, {writeConcern: <document>})
# 单条插入 db.user.insert({_id: 1, name:"zhangsan", age:20}) # insert: 若插入的数据主键已经存在,则会抛 DuplicateKeyException 异常,提示主键重复,当前数据保存失败 db.user.save({_id: 1, name:"lisi", age:21}) # save: 若 _id 主键存在则更新数据,如果不存在就插入数据 # 批量插入 db.user.insertMany([{name:"wangwu", age:22}, {name:"zhaoliu", age:23}]) # 批量插入 db.user.insert([{name:"wangwu", age:22}, {name:"zhaoliu", age:23}]) # insert和save也可以实现批量插入 db.user.save([{name:"wangwu", age:22}, {name:"zhaoliu", age:23}])
- 通过js脚本插入数据: books.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.books.insertMany(books);
- 命令行插入:
再通过mongo命令行加载js文件:load("books.js")
;或者直接将 books.js 文件内容在mongo命令行执行即可。
-
查询文档
db.collection.find(query, projection)
db.collection.findOne(query, projection)
参数 - query :可选,使用查询操作符指定查询条件。 - projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。投影时,_id为1的时候,其他字段必须是1;_id是0的时候,其他字段可以是0;如果没有_id字段约束,多个其他字段必须同为0或同为1。
如果查询返回的条目数量较多,mongo shell则会自动实现分批显示。默认情况下每次只显示20条,可以输入命令
it
读取下一批。db.books.find({tag:"nosql"}) # 查询带有nosql标签的数据行: db.books.find({_id:ObjectId("61caa09ee0782536660494d9")}) # 按_id查 db.books.find({type:"travel",favCount:{$gt:60}}) # 查询分类为“travel”、收藏数大于60个的数据行 db.books.find({}).pretty() # 格式化展示,方便观看 db.books.find({}, {title:1, type:1, tag:1, favCount:1, author:1}) # 查询指定的列。如果没有_id字段约束,多个其他字段必须同为0或同为1。
查询条件对照表:
MQL SQL {a: 1} a = 1 {a: {$ne: 1}} a <> 1 {a: {$gt: 1}} a > 1 {a: {$gte: 1}} a >= 1 {a: {$lt: 1}} a < 1 {a: {$lte: 1}} a <= 1 逻辑查询对照表:
MQL SQL {a:1, b:1} 或 {$and: [{a: 1}, {b: 1}]} a = 1 AND b = 1 {$or: [{a: 1}, {b: 1}]} a = 1 OR b = 1 {a: {$exists: false}} a IS NULL {a: {$in: [1, 2, 3]}} a IN (1, 2, 3) -
正则表达式匹配查询
db.books.find({type:/so/}) # 使用正则表达式查找type包含"so"字符串的数据行
-
排序:
sort()
1=升序;-1=降序db.books.find({type:"travel"}).sort({favCount:-1}) # 指定按收藏数(favCount)降序返回
-
分页:
skip()
skip用于指定跳过记录数,limit则用于限定返回结果数量。可以在执行find命令的同时指定skip、limit参数,以此实现分页的功能。db.books.find().skip(8).limit(4) # 假定每页大小为8条,查询第3页的book文档:
-
-
更新文档
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文档被收藏了,则需要将该文档的favCount字段自增 db.books.update({_id:ObjectId("61caa09ee0782536660494d9")}, {$inc:{favCount:1}})
-
更新多个文档
默认情况下,update命令只在更新第一个文档之后返回,如果需要更新多个文档,则可以使用multi
选项。# 将分类为“novel”的文档的增加发布时间(publishedDate) db.books.update( {type:"novel"}, {$set:{publishedDate:new Date()}}, {"multi":true} )
update命令的选项配置较多,为了简化使用还可以使用一些快捷命令:
updateOne: 更新单个文档 updateMany: 更新多个文档 replaceOne: 替换单个文档 db.user.updateMany({name:/u/}, {$inc: {age: 5}}) # 给名字中含有 'u' 的用户年龄 加5岁。
-
目标文档不存在就插入
upsert是一种特殊的更新,其表现为如果目标文档不存在,则执行插入命令。db.books.update( {title:"my book"}, {$set:{tags:["nosql","mongodb"], type:"none", author:"fox"}}, {upsert:true} )
-
返回查询结果并修改
findAndModify
findAndModify兼容了查询和更新指定文档的功能,findAndModify只能更新单个文档。db.books.findAndModify({ query:{_id:ObjectId("61caa09ee0782536660494dd")}, update:{$inc: {favCount:1}} })
该操作会返回符合查询条件的文档数据,并完成对文档的修改,默认情况下,findAndModify 会返回修改前的“旧”数据。如果希望返回修改后的数据,则可以指定
new
选项。db.books.findAndModify({ query: {_id:ObjectId("61caa09ee0782536660494dd")}, update: {$inc: {favCount:1}}, new: true })
-
更新单个文档并返回更新前(或更新后)的文档:
findOneAndUpdate
用法同上。 -
替换单个文档并返回替换前(或替换后)的文档:
findOneAndReplace
用法同上。
-
-
删除文档
指定一个空文档条件会删除所有文档。
-
delete
删除
官方推荐使用 deleteOne() 和 deleteMany() 方法删除文档。db.books.deleteMany({}) # 删除集合下全部文档 db.books.deleteMany({type: "novel"}) # 删除 type等于 novel 的全部文档 db.books.deleteOne({type: "novel"}) # 删除 type等于novel 的一个文档
-
remove
删除db.user.remove({age:28}) # 删除age等于28的记录 db.user.remove({age: {$lt: 25}}) # 删除age小于25的记录 db.user.remove({}) # 删除所有记录 db.user.remove() # 报错
remove
命令会删除匹配条件的全部文档,如果希望明确限定只删除一个文档,则需要指定justOne
参数,命令格式:db.collection.remove(query,justOne)
db.books.remove({type:"novel"},true) # 删除满足type:novel条件的首条记录
注意: remove、deleteMany等命令需要对查询范围内的文档逐个删除,如果希望删除整个集合,则使用drop命令会更加高效。
-