MongoDB学习笔记
概念篇
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的、面向文档存储的开源数据库系统。
- 介于关系型数据库与非关系型数据库之间
- 更偏向于关系型数据库
数据结构由key/value组成,类似于JSON结构。
MongoDB将数据存放在
db目录
中。- 这个目录应由手工创建在根目录下。
MongoDB不支持多表连接。
MongoDB自动将_id字段设置为主键。
MongoDB的保留数据库:
- admin:从权限的角度来看,这是”root”数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。
- local:存储本地数据。
- config:保存分片信息
MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型。
MongoDB的数据库结构:数据库–>集合(表)–>文档(行)–>字段(列)
MongoDB数据类型:
数据类型 描述 String 字符串 Integer 整数 Boolean 布尔值 Double 双精度浮点数 Array 数组 Timestamp 时间戳 Date 日期 - - Object 用于内嵌文档,存储文档对象 Null 空值 Symbol 符号(=字符串),用于采用特殊符号的语言 Object ID 对象ID Binary Data 二进制数据 Code 代码,用于存储JavaScript代码 Regular Expression 正则表达式 Object ID构成方式:
- 时间戳 + 机器标识码 + 进程PID + 随机数
- 如图1所示
CRUD篇
创建数据库:
use database_name
- 如果数据库不存在,则创建数据库,否则切换到指定数据库。
show dbs
:查看所有具有数据的数据库(空数据库除外)db
:查看当前数据库- MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
删除数据库:
db.dropDatabase()
- 删除当前数据库,默认为test。
删除集合(表):
// collection为集合名 db.collection.drop()
- 删除当前数据库下的指定集合
- 返回值:
- 成功删除集合,返回true
- 删除失败,返回false
创建集合(表):
// name:集合名,如:"table_01" db.createCollection(name, options)
在当前数据库中创建name表
show tables
或show collections
: 查看当前数据库中的所有集合options参数:
参数 类型 描述 capped 布尔 如果为 true,则创建固定集合(固定大小的集合) size 数值 为固定集合指定一个最大值 max 数值 指定固定集合中包含文档的最大数量 在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
插入文档:
文档的数据结构:BSON(Binary JSON,一种类似 JSON 的二进制形式的存储格式)
// collection: 集合名;document:数据 db.collection.insert(document) // save()在新版本中已废弃 db.collection.save(document) /* * 3.2版本新增的方法 */ // 向集合中插入1个文档 db.collection.insertOne( <document>, { writeConcern: <document> } ) // 向集合中插入1个 / 多个文档 db.collection.insertMany( [ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> } )
仅仅是插入数据,若插入数据的主键存在,则抛出org.springframework.dao.DuplicateKeyException
3.2版本新增方法参数说明:
参数 类型 描述 document JSON 要插入的文档 writeConcern Integer 写入策略,默认为 1,即要求确认写操作,0 是不要求。 ordered Boolean 指定是否按顺序写入,默认 true,按顺序写入。 主键ID自动生成,无需插入。
插入文档时,如果集合不存在,则MongoDB会自动创建集合并把文档插入其中。
定义变量:
document = ({ title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库' })
更新文档:
/* 方法一 */ db.collection.update( <query>, <update>, { upset: <Boolean>, multi: <Boolean>, writeConcern: <document> } ) 示例: db.col.update( {'title':'MongoDB 教程'}, {$set:{'title':'MongoDB'}} ) /* 方法二 */ db.collection.save( <document>, { writeConcern: <document> } ) 示例: db.col.save({ "_id" : ObjectId("56064f89ade2f21f36b03136"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Runoob", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "NoSQL" ], "likes" : 110 })
update()方法参数说明:
参数 类型 必选 描述 query 语句 是 update的查询条件,类似sql update查询内where子句 update 语句 是 update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set子句 upset Boolean 否 upset(= update + insert)如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入 multi Boolean 否 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新 writeConcern Integer 否 抛出异常的级别
删除文档:
db.collection.remove( <query>, { justOne: <boolean>, writeConcern: <document> } ) // 删除集合里的所有文档 db.collection.remove({})
remove()方法的参数:
参数 类型 必选 描述 query JSON 否 删除的文档条件 justOne Boolean 否 如果设为 true 或 1,则只删除一个文档,如果不设置该参数或使用默认值 false,则删除所有匹配条件的文档 writeConcern Integer 否 抛出异常的级别 删除文档前,先查询文档,避免误删除。
查询文档:
/* 方法一: */ db.collection.find(<query>, <projection>) /* 方法二: */ db.collection.findOne() 示例: db.collection.find({ title: "Java教程" }, { title: 1, _id: 0 } )
find()方法的参数说明:
参数 类型 必选 描述 query JSON 否 使用查询操作符指定查询条件 projection JSON 否 使用投影操作符指定返回的键 find()方法以非结构化的方式显示所有文档
pretty()方法以格式化的方式显示所有文档
- 使用方法:
db.collection.find().pretty()
- 使用方法:
MongoDB的条件语句查询:
操作 格式 范例 RDBMS语句 等于 { : } db.col.find({“by”:”菜鸟教程”}).pretty() where by = ‘菜鸟教程’ 小于 { :{$lt: }} db.col.find({“likes”:{$lt:50}}).pretty() where likes < 50 小于或等于 { :{$lte: }} db.col.find({“likes”:{$lte:50}}).pretty() where likes <= 50 大于 { :{$gt: }} db.col.find({“likes”:{$gt:50}}).pretty() where likes > 50 大于或等于 { :{$gte: }} db.col.find({“likes”:{$gte:50}}).pretty() where likes >= 50 不等于 { :{$ne: }} db.col.find({“likes”:{$ne:50}}).pretty() where likes != 50 And条件:
- find()方法中的
传入多个键,每个键以逗号隔开。 - 使用方法:
db.col.find({key1:value1, key2:value2}).pretty() 示例: db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()
- find()方法中的
Or条件:
- find()方法中的
使用 $or
关键字作为键 - 使用方法:
db.collection.find( { $or: [ {key1: value1}, {key2: value2} ] } ) 示例: db.col.find( { $or:[ {"by":"菜鸟教程"}, {"title": "MongoDB 教程"} ] } ).pretty()
- find()方法中的
$type
:用来匹配集合中字段的数据类型。- 使用方法:
// 用来匹配集合中title字段类型为String的文档 db.collection.find({ "title": {$type: "string"} })
- 使用方法:
limit()方法:
// 读取集合中指定数量的记录 db.collection.find().limit(<number>) 示例: db.col.find({},{"title":1, _id:0}).limit(2)
limit()方法参数说明:
参数 类型 必选 描述 number Integer 是 读取的记录条数
- skip()方法:
// 跳过集合中指定数量的记录 db.collection.find().limit(<number>).skip(<number>) 示例: db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
- skip()方法的默认参数为0。
- sort()方法:
// 根据指定的字段对数据进行排序 db.collection.find().sort({ key: 1 / -1 }) 示例: db.col.find( {}, { title: 1, _id: 0 } ).sort({ likes: -1 } )
sort()方法的参数说明:
参数 类型 必选 描述 key String 是 要排序的字段名 value Integer 是 排序方式(1:升序;-1:降序) 排序方式如图2所示。
- 索引:
定义:对数据库表中的一列 / 多列的值进行排序的一种结构。
// 用于在指定的列上创建索引 db.collection.createIndex(<keys>, <options>) 示例: db.collection.createIndex({ "title": 1, "like": -1 }, { background: true })
createIndex()方法的参数说明:
参数 类型 必选 描述 keys JSON 是 要创建索引的字段(1 为指定按升序创建索引,-1为按降序来创建索引) -options JSON 否 可选参数 background Boolean 否 指定以后台方式创建索引,默认为false unique Boolean 否 指定是否创建唯一索引,默认为false name String 否 索引的名称,默认为索引对应的字段名 + 排序顺序 sparse Boolean 否 对文档中不存在的字段数据不启用索引(如果启用,则在索引字段中不会查询出没有包含对应字段的文档),默认为false expireAfterSeconds Integer 否 集合的生存时间 v 否 索引的版本号 weights JSON 否 索引的权重值 (数值在 1 到 99,999 之间),表示该索引相对于其他索引字段的得分权 default_language String 否 决定了停用词及词干和词器的规则的列表 language_override String 否 指定了包含在文档中的字段名
- 聚合:
// 用于计算数据,并返回计算后的结果(平均值、求和) db.collection.aggregate(<aggregate_operation>)
聚合表达式:
表达式 描述 $sum 求和 $avg 求平均值 $min 求最小值 $max 求最大值 - - $push 在结果文档中,插入值到一个数组中 $addToSet 在结果文档中,插入值到一个数组中,但不创建副本 - - $first 获取第1个文档的数据 $last 获取最后1个文档的数据 聚合管道:
将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。
常用操作:
操作名称 描述 $project 修改输入文档的结构 $match 过滤数据,只输出符合条件的文档 $limit 限制聚合管道返回的文档数 $skip 跳过指定数量的文档,并返回剩下的文档 $unwind 拆分文档中的数组类型字段 $group 文档分组 $sort 文档排序 $geoNear 输出接近某一地理位置的有序文档 示例:
/* $project示例 */ db.collection.aggregate({ $project: { _id: 0, // 输出的文档中不包含_id字段,默认包含 title: 1, author: 1 } }) /* $match示例 */ // 获取70 < score <= 90的数据,并统计数量 db.collection.aggregate([ { $match: {score: {$gt: 70}, {$lte: 90}} }, { $project: { _id: 0, count: {$sum: 1} } } ]);
高级篇
数据备份:
// 导出MongoDB所有数据到指定目录中 mongodump -h(/ --host) <dbhost> -p(/ --port) <portnumber> -d(/ --db) <dbname> -o(/ --out) <backdirectory> -c(/ --collection) <collection>
mongodump命令参数说明:
参数 描述 dbhost MongDB所在服务器地址,例如:127.0.0.1 portnumber 端口号 dbname 需要备份的数据库实例名称 backdirectory 备份的数据存放位置,该目录需要提前建立 collection 需要备份的集合名称
数据恢复:
// 恢复备份的数据 mongorestore -h(/ --host) <hostname><:port> -d(/ --db) <dbname> <path> --drop
- mongorestore命令参数说明:
参数 描述 –drop 先删除当前数据,然后恢复备份的数据 path 设置备份数据所在位置
- mongorestore命令参数说明:
MongoDB监控:
mongostat命令
:自带的状态检测工具,间隔固定时间获取mongodb的当前运行状态。- 使用方法:
mongostat
- 使用方法:
mongotop命令
:用来跟踪一个MongoDB的实例,查看哪些时间大量花费在读取和写入数据使用方法:
mongotop <sleeptime> --locks
mongotop命令参数说明:
参数 类型 必选 描述 sleeptime Integer 否 等待的时间长度,以秒为单位 locks - 否 报告数据库中每个锁的使用
Java API:
- 前往MongoDB驱动下载页面下载驱动jar包
mongo-java-driver-3.2.2.jar
- 使用方法:
// 连接MongoDB服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接数据库-getDatabase() MongoDatabase database = mongoClient.getDatabase("test"); // 创建集合(表)-createCollection() database.createCollection("test"); // 获取集合-getCollection() MongeCollection<Document> collection = database.getCollection("test"); // 插入文档-insertMany() /** * 1. 创建key-value格式的文档org.bson.Document * 2. 创建文档集合List<Document> * 3. 将文档插入到集合中 */ Document document = new Document("title", "MongoDB").append("author", "hao3") List<Document> documentList = new ArrayList<>(); documentList.add(document); collection.insertMany(documentList); // 更新文档-updateMany() /* 将文档中likes=100的文档修改为likes=200 */ collection.updateMany( Filters.eq("likes", 100), new Document( "$set", new Document( "likes", 200 ) ) ); // 删除文档-remove(), deleteOne(). deleteMany() /** * 1. 先用com.mongodb.DBCollection.findOne()方法获取第一个文档。 * 2. 再使用remove()方法删除 */ /* 删除符合条件的第一个文档 */ collection.deleteOne(Filters.eq("likes", 200)); /* 删除所有符合条件的文档 */ collection.deleteMany (Filters.eq("likes", 200)); //检索文档-find() /** * 1. 获取迭代器FindIterable<Document> * 2. 获取游标MongoCursor<Document> * 3. 通过游标遍历检索出的文档集合 */ FindIterable<Document> findIterable = collection.find(); MongoCursor<Document> mongoCursor = findIterable.iterator(); while(mongoCursor.hasNext()){ System.out.println(mongoCursor.next()); }
- 前往MongoDB驱动下载页面下载驱动jar包