MongoDB的安装及基本操作
MongoDB
MongoDB是一个开源文档数据库,提供高性能、高可用性和自动扩展
MongoDB的中的一条记录就是一个文档,是一个数据结构,由字段和值对组成.MongoDB文档与JSON对象类似。字段的值有可能包括其它文档,数组以及文档数组。
使用文档的优势在于:
- 文档(即对象)对应于许多编程语言中的本机数据类型。
- 嵌入文档及数组减少了昂贵的加入操作的需求。
- 动态的设计模式支持流畅的多态。
高性能
MongoDB中提供高性能的数据持久化。
- 对嵌入式数据模型的支持减少了数据库系统的I / O活动。
- 索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。
丰富语言查询
MongoDB支持丰富的查询语言以支持读写操作(CRUD)以及:
query:文本检索<$ text>
doc:地理空间查询</ tutorial / geospatial-tutorial>
。
高可用性:
MongoDB的复制设施,也叫作:ref,提供了:自动故障恢复以及数据冗余
甲副本集是一组保持相同的数据集,从而提供冗余和提高数据可用性的MongoDB服务器。
扩展水平能力
MongoDB提供水平可伸缩性作为其核心 功能的一部分:
- 分片在一组计算机集群分布数据。
- Tag aware分片运行直接将数据引导到特定的分片,例如,考虑分片的地理分布等,
MongoDB支持多种存储引擎
-
WiredTiger存储引擎:是在3.0之后,加入的一款新的存储引擎。WiredTiger 采用了b-tree来组织管理数据, 一个集合的Namespace, 来关联到该集合的索引, 通过索引可以有效地将感兴趣的部分数据加载到内存中, 通常会放进Cache里面, 以备后续使用。 将数据从磁盘读入内存或者从内存flush到磁盘的基本操作单位是一个内存页。
MMAPV1: MongoDB的原始存储引擎,在第一个版本中引入,从4.0版本开始被弃用。
相对于MMAPv1,MongoDB可以压缩最大80%的空间,这样可以大大的提升磁盘空间的利用率
BSON
JSON是一种简单的数据表示方式,它易于理解、易于解析、易于记忆。但从另一方面来说,因为只有null、布尔、数字、字符串、数组和对象这几种数据类型,所以JSON有一定局限性。例如,JSON没有日期类型,JSON只有一种数字类型,无法区分浮点数和整数,更别说区分32为和64位数字了。再者,JSON无法表示其他一些通用类型,如正则表达式或函数。
MongoDB将数据记录存储为BSON文档。BSON是JSON文档的二进制表示,但它包含的数据类型多于JSON。MongoDB文档由字段和值对组成,字段的值可以是任何BSON 数据类型,包括其他文档,数组和文档数组。
基本数据类型:
null、布尔型、数值、字符串、日期、正则表达式、内嵌文档(文档可以嵌套其他文档,被嵌套的文档作为值来处理)、对象id(对象id是一个12字节的字符串,是文档的唯一标识)、二进制数据、代码
BSON 与 MongoDB 的关系
BSON是用于存储MongoDB【文档】的一种文档格式。驱动程序在使用【文档】进行插入、查询或其他操作时。会先将【文档】编码成BSON格式,然后发送给服务器。同样地,服务器将文档返回客户端时,也是已BSON格式进行的。驱动程序先对此BSON进行解码然后再传送给客户端。因此,BSON与MongoDB的关系为:MongoDB利用BSON格式存储数据和传输数据
MongoDB CRUD操作
创建或插入操作即向 集合集合添加新的 文档文件。如果插入时集合不存在,插入操作会创建该集合。
插入文档
MongoDB的中提供了以下方法来插入文档到一个集合:
-
在MongoDB中,插入操作作用于单个集合集合 .MongoDB中所有的写操作在 单个集合文档的层级上是原子性。
读
读操作获取集合收集中的文档文件 ;例如查询一个集合中的文档.MongoDB提供了如下方法从集合中读取文档:db.collection.find()
更新操作
更新操作修改 集合 collection 中已经存在的 文档 documents。
db.collection.updateOne()
即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新一个文档。3.2新版功能。 db.collection.updateMany()
更新所有通过过滤条件匹配到的文档。3.2新版功能。 db.collection.replaceOne()
即使可能有多个文档通过过滤条件匹配到,但是也最多也只替换一个文档。3.2新版功能。 db.collection.update()
即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新或者替换一个文档。默认情况下, db.collection.update()
只更新一个文档。要更新多个文档,请使用 多选项。
删除操作
删除是从一个集合中删除文档的操作。
db.collection.remove() |
删除单个文档或与指定过滤器匹配的所有文档。 |
---|---|
db.collection.deleteOne() |
即使多个文档可能与指定的过滤器匹配,也最多删除与指定过滤器匹配的单个文档。3.2新版功能。 |
db.collection.deleteMany() |
删除所有匹配指定过滤条件的文档。 |
聚合:
什么是聚合:聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
语法:db.集合名称.aggregate({管道:{表达式}})
常用管道命令:
在mongodb中,⽂档处理完毕后, 通过管道进⾏下⼀次处理 常用管道命令如下:
$group: 将集合中的⽂档分组, 可⽤于统计结果
$match: 过滤数据, 只输出符合条件的⽂档
$project: 修改输⼊⽂档的结构, 如重命名、 增加、 删除字段、 创建计算结果
$sort: 将输⼊⽂档排序后输出
$limit: 限制聚合管道返回的⽂档数
$skip:跳过指定数量的文档,并返回余下的文档
常用表达式
表达式:处理输⼊⽂档并输出 语法:表达式:'$列名'
常⽤表达式:
$sum: 计算总和
$sum:1 表示以⼀倍计数
$avg: 计算平均值
$min: 获取最⼩值
$max: 获取最⼤值
$push: 在结果⽂档中插⼊值到⼀个数组中
数据模型
数据模型设计介绍:
MongoDB 的数据模式是一种 灵活模式 。关系型数据库要求你在插入数据之前必须先定义好一个表的模式结构,而MongoDB的 集合 则并不限制 document 结构。这种灵活性让对象和数据库文档之间的映射变得很容易。 即使数据记录之间有很大的变化,每个文档也可以很好的映射到各条不同的记录。 当然在实际使用中,同一个集合中的文档往往都有一个比较类似的结构。
数据模型设计中最具挑战性的是在应用程序需求,数据库引擎性能要求和数据读写模式之间做权衡考量。当设计数据模型的时候,一定要考虑应用程序对数据的使用模式(如查询,更新和处理)以及数据本身的天然结构。
文档结构
设计基于MongoDB的应用程序的数据模型时的关键就是选择合适的文档结构以及确定应用程序如何描述数据之间的关系。有两种方式可以用来描述这些关系: 引用 及 内嵌 。
References - 引用
引用方式通过存储链接或者 引用 信息来实现两个不同文档之间的关联。应用程序可以通过解析这些 数据库引用 来访问相关数据。简单来讲,这就是 规范化 的数据模型。
Embedded Data - 内嵌
内嵌方式指的是把相关联的数据保存在同一个文档结构之内。MongoDB的文档结构允许一个字段或者一个数组内的值为一个嵌套的文档。这种 冗余 的数据模型可以让应用程序在一个数据库操作内完成对相关数据的读取或修改。
mongodb与mysql区别
安装
wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.8.tgz
mv mongodb-linux-x86_64-rhel70-4.2.8 /usr/local/mongodb
cd /usr/local/mongodb/
mkdir -p /data/db
export PATH=/usr/local/mongodb/bin:$PATH #添加环境变量
/usr/local/mongodb/bin/mongod --dbpath=/data/db --logpath=/usr/local/mongodb/mongodb.log --logappend&
--dbpath 指定存放数据文件的目录
--logpath 指定mongo日志的路径
& 后台启动
/usr/local/mongodb/bin/mongo #连接mongodb
数据库的操作
列出所有的数据库
show dbs;
查看当前正在使用哪个数据库
> db #当前处在哪个数据库
test
> db.getName() #返回当前数据库的名字
test
> use python2002 有的话 切换到 python2002 没有的话先创建 刚开始创建show dbs 看不到数据库 因为没有数据
> db.python2002.insert({name:"kangbazi",password:'123456'}) #创建一个数据 默认会存在一个以数据库为命名的集合
WriteResult({ "nInserted" : 1 })
> db.dropDatabase() #删除当前数据库 处在哪个数据库 就删除哪个数据库
{ "dropped" : "python2002", "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
help 查看帮助
exit #退出
集合的操作
> db.createCollection('dandan');#创建一个集合
{ "ok" : 1 }
> db.dandan.insert({name:'dandan',password:'654321'}) #db.集合的名字.insert({name:'123123'})
WriteResult({ "nInserted" : 1 })
> show collections; #列出所有的集合
dandan
python2002
> db.dandan.drop() #删除集合
true
文档的操作
#插入数据
> db.dandan.insert({name:'dandan1',password:'123123'},{name:'dandan2',password:'123456'},{name:'dandan3',password:'123789'}); #同时插入多条
WriteResult({ "nInserted" : 1 })
> db.dandan.save({name:'xingxing',password:'dengdeng'}) #如果这里边没有id字段 它跟上面的insert方法是一样一样
WriteResult({ "nInserted" : 1 })
> db.dandan.save({"_id" : ObjectId("5f1a554cc43cca4fc20f6764"),name:'dandan888',password:'999999'})#如果指定了id 相当于对数据进行更新操作
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.dandan.findOne({_id:ObjectId("5f1a554cc43cca4fc20f6764")})
{
"_id" : ObjectId("5f1a554cc43cca4fc20f6764"),
"name" : "dandan888",
"password" : "999999"
}
## 更新文档 update
db.dandan.update({查询条件},{$set:{属性名:值}}) #直接修改属性
> db.dandan.update({name:'dandan888'},{$set:{name:'dandan666',password:'77777'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.dandan.findOne({_id:ObjectId("5f1a554cc43cca4fc20f6764")})
{
"_id" : ObjectId("5f1a554cc43cca4fc20f6764"),
"name" : "dandan666",
"password" : "77777"
}
> db.dandan.update({name:'kangbazi'},{$inc:{age:20}}) #$inc累加指定的值
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.dandan.findOne({name:'kangbazi'})
{
"_id" : ObjectId("5f1a5847c43cca4fc20f6766"),
"name" : "kangbazi",
"age" : 38
}
## 删除文档
> db.dandan.remove({name:'kangbazi'})
WriteResult({ "nRemoved" : 1 })
## 查找
db.集合名称.find() #查询所有
db.集合名字.findOne({name:'kangbazi'}) #查询name为kangbazi的一条文档
> db.zhifei.findOne({age:{$gt:19}}) #年龄大于19岁的一条数据
{
"_id" : ObjectId("5f1a5cbbc43cca4fc20f676d"),
"name" : "123123",
"age" : 20
}
> db.zhifei.find({age:{$gt:19}}) #年龄大于19岁的多条数据
{ "_id" : ObjectId("5f1a5cbbc43cca4fc20f676d"), "name" : "123123", "age" : 20 }
{ "_id" : ObjectId("5f1a5cbbc43cca4fc20f676e"), "name" : "456456", "age" : 25 }
>
$gt 大于
$lt 小于
$eq 等于
$gte 大于等于
$gte 小于等于
#根据 id去查询
> db.zhifei.find({'_id':ObjectId("5f1a5cbbc43cca4fc20f676d")})
{ "_id" : ObjectId("5f1a5cbbc43cca4fc20f676d"), "name" : "123123", "age" : 20 }
> db.zhifei.find({name:/123456/})
{ "_id" : ObjectId("5f1a5aa7c43cca4fc20f6768"), "name" : "123456" }
{ "_id" : ObjectId("5f1a5affc43cca4fc20f6769"), "name" : "123456" }
> db.zhifei.find({name:/123/})
{ "_id" : ObjectId("5f1a5aa7c43cca4fc20f6768"), "name" : "123456" }
{ "_id" : ObjectId("5f1a5affc43cca4fc20f6769"), "name" : "123456" }
{ "_id" : ObjectId("5f1a5affc43cca4fc20f676a"), "name" : "123123" }
{ "_id" : ObjectId("5f1a5cbbc43cca4fc20f676d"), "name" : "123123", "age" : 20 }
> db.zhifei.find({name:/^123$/})
# and 两个条件一起
> db.zhifei.find({name:/123/,age:20})
{ "_id" : ObjectId("5f1a5cbbc43cca4fc20f676d"), "name" : "123123", "age" : 20 }
#or 或者
db.zhifei.find({$or:[{条件1},{条件2}]})
> db.zhifei.find({$or:[{name:'123123'},{age:20}]})
{ "_id" : ObjectId("5f1a5affc43cca4fc20f676a"), "name" : "123123" }
{ "_id" : ObjectId("5f1a5cbbc43cca4fc20f676d"), "name" : "123123", "age" : 20 }
上一篇: 配置mongodb复制集时遇见的坑
下一篇: 从另一个分支在Git中创建一个分支