简介
MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组。
MongoDB是专为可扩展性,高性能和高可用性而设计的数据库。它可以从单服务器部署扩展到大型、复杂的多数据中心架构。利用内存计算的优势,MongoDB能够提供高性能的数据读写操作。MongoDB的本地复制和自动故障转移功能使您的应用程序具有企业级的可靠性和操作灵活性。
概念解析
database:数据库
MongoDB的默认数据库为"db",该数据库存储在data目录中。
数据库名可以是满足以下条件的任意UTF-8字符串。
> 不能是空字符串("")
> 不得含有' '(空格)、.、$、/、\和\0 (空字符)
> 应全部小写
> 最多64字节
> 保留的数据库名:admin(root数据库)、local(存储限于本地单台服务器的集合)、config(保存分片的相关信息)
collection:数据库表/集合
合法的集合名
> 集合名不能是空字符串""。
> 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
> 集合名不能以"system."开头,这是为系统集合保留的前缀。
> 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
Capped collections:固定大小的collections。它有很高的性能以及队列过期的特征(过期按照插入的顺序)。
document:数据记录行/文档,是一组键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型。
需要注意的是:
> 文档中的键/值对是有序的。
> 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
> MongoDB区分类型和大小写。
> MongoDB的文档不能有重复的键。
> 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
> 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
> .和$有特别的意义,只有在特定环境下才能使用。
> 以下划线"_"开头的键是保留的(不是严格要求的)。
field:数据字段/域
index:索引
primary key:主键,MongoDB自动将_id字段设置为主键
数据类型
String:字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8编码的字符串才是合法的。
Integer:整型数值。用于存储数值。根据你所采用的服务器,可分为32位或64位。
Boolean:布尔值。用于存储布尔值(真/假)。
Double:双精度浮点值。用于存储浮点值。
Min/Max keys:将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
Array:用于将数组或列表或多个值存储为一个键。
Timestamp:时间戳。记录文档修改或添加的具体时间。给MongoDB_内部_使用。
Object:用于内嵌文档。
Null:用于创建空值。
Symbol:符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
Date:日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID:对象 ID。用于创建文档的 ID。类似唯一主键,可以很快的去生成和排序,包含 12bytes。(4个时间戳+3个机器标识码+2个PID(进程id)+3个自增计数(初始化为随机值))
Binary Data:二进制数据。用于存储二进制数据。
Code:代码类型。用于在文档中存储 JavaScript 代码。
Regular expression:正则表达式类型。用于存储正则表达式。
JavaScript: JavaScript
JavascriptWithScope: JavaScript (带范围)
Decimal: 小数128 Decimal128
连接
// MongoDB服务 - 标准URI连接语法
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
// 注:1. 使用用户名和密码连接到MongoDB服务器,连接并验证登录指定数据库。若不指定,默认打开 test 数据库
// 2. portX 可选的指定端口,如果不填,默认为27017
// 3. ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开
// 标准的连接格式包含了多个选项(options)。键值对之间通过&或;(分号)隔开
replicaSet=name:验证replica set的名称。 Impliesconnect=replicaSet.
slaveOk=true|false:true: 在connect=direct模式下,驱动会连接第一台机器,即使这台服务器不是主。在connect=replicaSet模式下,驱动会发送所有的写请求到主并且把读取操作分布在其他从服务器。false: 在connect=direct模式下,驱动会自动找寻主服务器. 在connect=replicaSet模式下,驱动仅仅连接主服务器,并且所有的读写命令都连接到主服务器。
safe=true|false:true: 在执行更新操作之后,驱动都会发送getLastError命令来确保更新成功。(还要参考 wtimeoutMS)。 false: 在每次更新之后,驱动不会发送getLastError来确保更新成功。
w=n:驱动添加{w:n}到getLastError命令。应用于safe=true。
wtimeoutMS=ms:驱动添加{wtimeout:ms}到getlasterror命令. 应用于safe=true。
fsync=true|false:true: 驱动添加{fsync:true}到getlasterror命令。应用于safe=true。false: 驱动不会添加到getLastError命令中。
journal=true|false:如果设置为true, 同步到journal(在提交到数据库前写入到实体中)。 应用于safe=true
connectTimeoutMS=ms:可以打开连接的时间。
socketTimeoutMS=ms:发送和接受sockets的时间。
数据库操作
// 创建数据库,如果数据库不存在,则创建;否则切换到指定数据库
// MongoDB中默认的数据库为test,如果没有创建新的数据库,集合将存放在test库中
use database_name
// 查看当前数据库名
db
// 查看所有数据库
show dbs
// 删除数据库
db.dropDatabase()
集合操作
1. 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
2. 在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
// 创建集合
db.createCollection(name, options)
// 查看集合
show collections
show tables
// 删除集合。 如果成功删除选定集合,则drop()方法返回true,否则返回false。
db.collection.drop()
创建集合 - options参数
capped:如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
size:为固定集合指定一个最大值,即字节数。如果 capped 为 true,也需要指定该字段。
max:指定固定集合中包含文档的最大数量。
ps: 在插入文档时,MongoDB 首先检查固定集合的size字段,然后检查max字段。
文档操作
// 插入文档
// 若插入的数据主键已经存在,则会抛异常,提示主键重复,不保存当前数据。
db.COLLECTION_NAME.insert(document)
// 用于向集合插入一个新文档, 3.2版本之后新增
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
// 用于向集合插入多个文档, 3.2版本之后新增
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
// 更新文档
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
// 删除文档
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
// 查询文档
db.collection.find(query, projection)
// 条件语句: 等于 {<key>:<value>} 或者 {<key>:{ $eq: <value> }}
// 例:where age between 20 and 50 AND (username='fw' OR username='psl')
{"age":{$gte:20, $lte:50}, $or:[{"username":"fw"}, {"username":"psl"}]}
// limit(n): 读取指定数量的数据; skip(n): 跳过指定数量的数据。
// sort({key: 1[,key2: -1]]}): 对数据进行排序。其中1为升序,-1是降序
// 例:取11-20条数据,按用户名升序, 年龄降序
db.collection.find().limit(10).skip(10).sort({"username":1, "age": -1})
插入参数说明:
document:要写入的文档。
writeConcern:写入策略,默认为 1,即要求确认写操作;0 是不要求。
> 默认值:{"writeConcern": {"w": 1, "j": false, "wtimeout": 200}}
ordered:指定是否按顺序写入,默认 true,按顺序写入。
更新参数说明:
query: update的查询条件,类似sql update查询内where后面的。
update: update的对象和一些更新的操作符(见 操作符 > 更新操作符)等,也可以理解为sql update查询内set后面的
upsert: 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi: 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern: 可选,抛出异常的级别。
删除参数说明:
query :(可选)删除文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
writeConcern :(可选)抛出异常的级别。
查询参数说明:
query:可选,使用查询操作符指定查询条件
projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
索引操作
使用索引,在MongoDB中执行查询变得更加高效。但是索引太多会减慢其他操作,例如插入,删除和更新操作。
// 创建索引。 1 按升序创建索引,-1按降序创建索引
db.collection.createIndex({field: 1, field2: -1, ...}, options)
// 查询集合的所有索引
db.collection.getIndexes()
// 删除集合中的指定索引
db.collection.dropIndex(indexName / {field: 1, field2: -1, ...})
// 删除集合中的所有索引
db.collection.dropIndexes()
参数说明:
background:建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引。默认值为false。
unique:建立的索引是否唯一。指定为true创建唯一索引。默认值为false。
name:索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
sparse:对文档中不存在的字段数据不启用索引;如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档。默认值为 false。
expireAfterSeconds:指定一个以秒为单位的数值,完成TTL设定,设定集合的生存时间。
v:索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weights:索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language:对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override:对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language。
聚合操作
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
db.collection.aggregate(AGGREGATE_OPERATION)
聚合的表达式(group > accumulator)
$sum: 计算总和。
$avg: 计算平均值。
$min: 获取集合中所有文档对应值得最小值。
$max: 获取集合中所有文档对应值得最大值。
$push: 将值加入一个数组中,不会判断是否有重复的值。
$addToSet: 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。
$first: 根据资源文档的排序获取第一个文档数据。
$last: 根据资源文档的排序获取最后一个文档数据。
例: 查询男性与女性的最大年龄
db.collection.aggregate([{$group: {_id: "$sex", num_tutorial: {$max: "$age"} }}])
管道操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。{key: 0/1}:指定key是否被包含(0不包含、1包含);_id默认被包含;{newKey: "$oldKey"}:字段重命名。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。在$group之前相当于where条件;在$group之后相当于having条件
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。语法:{$group:{ _id:<expression>, <field1>:{<accumulator1>:<expression1>}, ...}}。_id:分组字段,必须存在,可以为 null。其余的计算字段是可选的,并使用<accumulator>运算符计算。<expression>为字段时使用"$key"
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
// 例:年龄在20-50之间的男性与女性人数
db.collection.aggregate([
{ $match:{ age: { $gte : 20, $lte : 50 } } },
{ $group:{ _id: "$sex", count: { $sum: 1 } } }
]);
// 例:男性与女性最大年龄与最小年龄, 并按性别升序排列
db.fw_test.aggregate([
{ $group: { _id: "$sex", maxAge: { $max: "$age" }, minAge:{ $min: "$age" } } },
{ $project: { _id: 0, sex:"$_id", maxAge: 1, minAge: 1 } },
{ $sort: { sex: 1 } }
])
操作符
// 评价查询操作符
// 取模计算
$mod
// 例:查询age取模10等于1的数据
db.student.find({age:{$mod:[10,1]}})
// 选择值匹配指定正则表达式的文档
$regex
// 对具有文本索引的字段执行文本搜索
$text
// 匹配满足JavaScript表达式的文档,
// 使用$where操作符将包含JavaScript表达式的字符串或完整的JavaScript函数传递查询系统
$where
// 逻辑查询操作符
// 用法:{<逻辑操作符>: [{field1: value1}, {field2: value2}, ...]}
$and、 $nor、 $not、 $or
// 比较查询操作符
// 用法:{field:{<比较操作符>: value}}, $in和$nin时value为数组
$gt、 $gte、 $lt、 $lte、 $eq、 $ne、 $in、 $nin
// 数组查询操作符
// 匹配包含查询中指定的所有元素的数组
$all
// 匹配数组元素个数
$size
// 数组字段中的元素匹配所有指定的$elemMatch条件(至少存在一个值满足筛选条件)
$elemMatch
// 元查询操作符 // 数据类型操作符, 基于BSON类型来检索集合中匹配的数据类型
$type
// 例:获取username为String的数据
// {"title":{$type:2}} 或 {"title":{$type:'string'}}
// 操作符对应的类型与数值:Double: 1; String: 2; Object: 3; Array: 4;
// Binary data: 5; Object id: 7; Boolean: 8; Date: 9; Null: 10;
// Regular Expression: 11; JavaScript: 13; Symbol: 14;
// JavaScript (with scope): 15; 32-bit integer: 16; Timestamp: 17;
// 64-bit integer: 18; Min key: 255(Query with -1); Max key: 127
// 判断字段是否存在
// 用法: {field: {$exists: true/false}
$exists
// 更新操作符
// 字段更新操作符
$mul、 $max、 $min、 $setOnInsert、 $currentDate
// 设置某一个字段的值
// 用法:{$set:{field:value}}
$set
// 对一个数字字段的某个field增加value
// 用法:{$inc:{field:value}}
$inc
// 字段重命名
// 用法:{$rename:{old_field_name:new_field_name}}
$rename
// 删除字段
// 用法:{$unset:{field:1}}
$unset
// 数组更新操作符
$each、 $sort、 $position
// 把value追加到field里。field一定是数组类型,如果field不存在,会新增一个数组类型加进去。
// 用法:{$push: {field: value}}
$push
// 追加多个值到数组字段内
// 用法:{$pushAll: {field: value_array}}
$pushAll
// 加一个值到数组内,而且只有当这个值不在数组内才增加。
// 用法:{$addToSet: {field: value}}
$addToSet
// 从数组field内删除一个等于value的值
// 用法:{$pull: {field: value}}
$pull
// 从数组field内删除多个值
// 用法:{$pullAll: {field: value_array}}
$pullAll
// 删除数组内的一个值
// 用法:{$pop: {field: 1/-1}}。1第一个值;-1最后一个值。只能是1或-1
$pop
shell命令
// 批量写入
db.collection.bulkWrite()
// 返回集合总数或匹配查询的结果集总数
db.collection.count()
// 删除集合中的一个文档
db.collection.deleteOne()
// 删除集合中的多个文档
db.collection.deleteMany()
// 返回集合的大小
db.collection.dataSize()
// 返回具有指定字段不同值的文档(去除指定字段的重复数据)
db.collection.distinct()
// 返回各种方法的查询执行信息
db.collection.explain()
// 查询单条数据
db.collection.findOne()
// 查询单条数据并替换
db.collection.findOneAndReplace()
// 查询单条数据并删除
db.collection.findOneAndDelete()
// 查询单条数据并更新
db.collection.findOneAndUpdate()
// 查询并修改
db.collection.findAndModify()
// 提供简单的数据聚合功能
db.collection.group()
// 判断集合是否为定容量
db.collection.isCapped()
// 重建当前集合的所有索引
db.collection.reIndex()
// 重命名集合名称
db.collection.renameCollection()
// 替换集合中的一个文档(一条数据)
db.collection.replaceOne()
// 返回当前集合的状态
db.collection.stats()
// 返回当前集合已使用的空间大小
db.collection.storageSize()
// 返回当前集合的总占用空间,包括所有文件和所有索引
db.collection.totalSize()
// 返回当前集合所有的索引所占用的空间大小
db.collection.totalIndexSize()
// 执行对集合验证操作
db.collection.validate()
其它命令
// 查看MongoDB版本号
db.version()
// 查看当前的存储引擎
db.serverStatus()