mongodb的基本使用
mongodb服务
mongodb是一个高效的文档型的Nosql数据库,文档数据内部使用类似于json格式的bson的数据格式,也就是二进制形式json格式。
mongodb服务
centos7下安装
下载MongoDB源码或者使用yum安装,可以到阿里云官网镜像下载该服务。rpm包下载地址https://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/4.2/x86_64/RPMS/,下载MongoDB-server的rpm文件,再使用yum安装。
使用yum安装后,会在usr/bin/目录下存放MongoDB相关的可执行文件如下,同时查看配置文件/etc/mongo.conf
/usr/bin/
/usr/bin/
mongosniff mongodb监测工具,作用类似于 tcpdump
mongodump MongoDB数据备份工具
mongoimport Mongodb数据导入工具
mongoexport Mongodb数据导出工具
bsondump 将 bson 格式的文件转储为 json 格式的数据
mongoperf
mongorestore MongoDB数据恢复工具
mongod MongoDB服务启动工具
mongostat mongodb自带的状态检测工具
mongofiles GridFS 管理工具,可实现二制文件的存取
mongooplog
mongotop 跟踪一个MongoDB的实例,查看哪些大量的时间花费在读取和写入数据
mongos 分片路由,如果使用了 sharding 功能,则应用程序连接的是 mongos 而不是 mongod
mongo 客户端命令行工具,其实也是一个 js 解释器,支持 js 语法
/etc/mongo.conf
该配置文件使用yaml格式,使用缩进分级管理,缩进只支持空格而不支持Tab,冒号和后面必须有空格
systemLog: destination: file # 目的地 logAppend: true # 使用追加模式 path: /var/log/mongodb/mongod.log # 使用该配置文件启动时的配置文件位置 storage: dbPath: /var/lib/mongo # 数据的储存路径 journal: enabled: true # 如何运行该进程,及其pid文件 processManagement: fork: true # 运行在后台的守护进程 pidFilePath: /var/run/mongodb/mongod.pid # pid文件位置location of pidfile timeZoneInfo: /usr/share/zoneinfo # 网络接口配置 net: port: 27017 bindIp: 0.0.0.0
这只是对mongoDB服务的简单配置,还可以做其他的配置。配置完成后,通过mongod这个可执行文件启动服务。执行mongod 时候,可以指定参数,常用的参数如下
参数 | 描述 |
--bind_ip | 绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP |
--bind_ip_all |
绑定到所有的ip上,类似0.0.0.0 |
--logpath | 指定MongoDB日志文件,注意是指定文件而不是目录,一般为/var/log/mongodb/mongo.log文件 |
--logappend | 使用追加的方式写日志 |
--dbpath | 指定数据库路径,默认/data/db |
--port | 指定服务端口号,默认端口27017 |
--serviceName | 指定服务名称 |
--serviceDisplayName | 指定服务名称,有多个mongodb服务时执行。 |
--install | 指定作为一个Windows服务安装。 |
--config filepath |
指定启动时使用的配置文件 |
--fork |
作为一个守护进程运行,必须使用--logpath指定日志路径 |
启动mongo服务
- 直接启动
直接运行mongod命令,指定参数,
- 守护进程启动
使用--fork参数可以启动为一个守护进程,自动创建一个子进程运行该mongo服务,但是启动时必须使用--logpath指定日志文件的位置,方便日志文件查看,可以使用默认也是常用的位置。/var/log/mongod/mongo.log
$ monood --fork --logpath /var/log/mongod/mongo.log
或者使用配置文件启动服务,在默认的配置文件中指定了该服务使用守护进程且以指定了默认的日志路径。
$ mongod --config /etc/mongod .conf
- 使用systemctl管理
使用systemctl管理需要在/lib/systemd/system/mongod.service文件,使用yum安装默认该文件已经存在且配置完好,直接使用systemctl start/stop/enable/reload/disable mongod
即可管理该mongo服务。
客户端
- 自带的客户端:mongo可执行文件
$ mongo
运行即可默认连接到本机的服务中。 - 可视化工具compass:https://www.mongodb.com/products/compass
- Python连接:pymongo库
基本概念
类比于关系型数据库中库,表,记录,字段等概念,MongoDB也有相似的概念。比较如下。
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
database | db | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
join |
嵌入式文档实现 |
表连接,MongoDB不支持 |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
mongodb中一条数据的方式如下
{ "_id" : ObjectId("5e4572707546cca214b48806"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "w3cschool", "url" : "http://www.w3cschool.cn", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
所有的数据都是使用key-value的形式进行保存的,_id字段是mongodb自动生成的一个唯一key,作为primary_key,唯一定位数据并增加查询速度。
命令
库操作
show dbs 显示所有数据库,默认存在admin, local, config库 db 显示当前库,默认为test,但是没有数据数据,show dbs看不到该库 use <db_name> 使用(没有则创建)指定库 db.dropDatabase() 删除当前库
数据增删改
使用use创建该库后,可以向该库中的一个集合写入文档数据。
# 一条数据 docdata = ({ name : "tom", age : 20, addr : "shanghai", language : ["python", "java", "" ] }) 插入数据(insert(), save()) db.users.insert(docdata) 在库下新建了一个users的collection用于存放每一条文档数据 更新数据(update()) db.<collection_name>.update( criteria, objNew, upsert, multi ) criteria: 查询条件,一个字典,例如 {_id:100} objNew : 需要更新的数据,一个字典 {name:"peter", age:28} upsert : 为True没有查到则插入,false则不插入 mutil : 默认只会更改查询的第一条,为True则全部更新 db.users.update({name:"tom"}, {name:"peter", age:28}, True, false) 删除(remove) db.collection.remove( # 语法 <query>, # {} ,查询条件 { justOne: <boolean>, # bool 一条或全部删除 writeConcern: <document> } ) db.users.remove({}, 1) # 删除所有数据
查询
普通查询
pretty() :结构化的显示,自动换行缩进,方便查看
find() :非结构化,一个长字符串
findone() : 返回一个文档
db.users.find() # 查看users集合中的全部文档信息 db.users.find().pretty() # 将查询后的信息进行格式化输出
条件查询
条件 |
符号 |
格式 | 范例 |
= |
|
{<key>:{<value> } |
db.users.find({age:30}).pretty() |
< |
|
{<key>:{$lt:value>}} |
db.users.find({"age":$lt:30}}).pretty() |
<= |
|
{<key>:{$lte:value>}} |
db.users.find({"age":{$lte:30).pretty() |
> |
|
{<key>:{$gt:value>}} |
db.users.find({"age":{$gt,30}}).pretty() |
>= |
|
{<key>:{$gte:value>}} |
db.users.find({"age":{$gte:30}}).pretty() |
!= |
|
{<key>:{$ne:value>}} |
db.users.find({"age":{$ne:30}}).pretty() |
逻辑运算
and db.users.find({name:"tom", age:20}) # name和age同时满足的and关系 or db.users.find({$or:[{k1:v1}, {k2:v2}]}) # 列表中k1和k2为两个条件,并声明为or关系 not db.users.find({$not:[{k1:v1}, {k2:v2}]}) exist db.users.find({addr:{$exist:true}}) # 存在addr的 type db.users.find({age:{$type:16}}) # age的类型为编号为16的类型
这些逻辑运算符也支持混合使用,处理复杂的逻辑关系
limit 和 skip db.users.find({age:{$lt:40}}) # 这是返回全部数据 .limit(5).skip(10) # 跳过10条只显示接下来的5条 sort:使用 1 和 -1 来指定排序的方式 db.users.find().sort({age:1}) # 按照age升序
分组聚合
db.users.aggregate([$group: {_id: "$name", count_num:{$sum:1}}]) # 按照name分组并作为结果文档的_id字段,值为该文档的name字段值,count_num字段值由与1进行sum得出
python接口
pymongo库
python推荐使用pymongo库连接并操作mongodb数据库服务,在各个平台均推荐直接使用pip install pymongo
的方式安装该库,安装pymongo时候,pip能够自动安装正确版本的bson依赖,如果通过其他方式分别安装两个库,他们的版本可能会不兼容而无法保证正常运行。安装pymongo库需要python的版本为2.7或者3.4+才能使用。
基本使用
db和collection对象
import pymongo # 连接获得客户端对象,以下两种连接方式均可 # client = pymongo.MongoClient(host="192.168.236.100", port=27071) client = pymongo.MongoClient("mongodb://192.168.236.100:27071") # 通过指定的name获取一个database对象,没有则创建 # db = client.db_name db = client["db_name"] # 通过指定的name获得一个collection对象,没有则创建 # col = db.colection_name col = db["collection_name"]
db对象和collection对象均可以使用字典key和属性访问的方式获取,通过python的__getattr__和__getitem__魔术方法实现。提供key获取而不单纯只用属性访问是因为可能存在不符合python标识符要求的name,例如super-users
pymongo的源码目录只有单层目录结构,可以方便的观察各个模块的作用从而方便的找到我们可能需要的源码内容,在pymongo的目录中,一些基本的文件如下。
collection.py # 主要包含Collection类对象信息 command_cursor.py # cursor类的基类定义信息,cursor对象用于返回多个结果时用于封装的容器对象, common.py # 基类定义 cursor.py # 主要包含Cursor对象,继承了基类 database.py # 主要包含database类对象信息 mongo_client.py # 客户端类对象 mongo_replica_set_client.py # 用于副本集, monitor.py # 监控相关 pool.py # 连接池相关信息 results.py # 查询,插入操作等执行后的结果对象,可以从结果获取相关信息 server.py # server对象 ......
文档
文档即储存的数据,一个文档相当于SQL中的一条记录或者元组,是一个单个的数据个体。文档内部使用的是键值对的方式保存,并且会提前按照索引提前进行排序,方便以后的查找。
键:键是值的属性描述,使用字符串形式,区分大小写,为UTF-8编码的字符
值:值是储存的数据,可以储存的数据类型包括,字符串,32及64位整数,双精度,时间戳(毫秒级),布尔和null类型, BSON数组, BSON对象
_id键
如果插入的数据不指定名为_id的值信息,插入数据时将会自动的添加一个该字段,并根据时间戳,值类型,数据长度,随机数来产生一个值,使用python会将该值封装为一个ObjectID对象,是一个bson.objectid.ObjectId
类型
增删改查
常用的使用方式如下
col = pymongo.MongoClient("mongodb://127.0.0.1:27017")["db_name"]["collection_name"] # 插入 col.insert_one({}) # 插入一条,数据为字典,返回一个Result对象,可以获取id值 col.insert_many([{}, {} ...]) # 插入一组数据 # 查询 res_many = col.find({"name":"tom"}, (name, age)) # 返回多条条件name=tom的数据,且数据只返回name和age两个字段信息 for r in res_many: # 查询的所有的数据集,一个cursor对象,遍历直接得到每一条数据 print(r) # 为字典类型,可直接使用 res = col.find_one({}, {name:False, age:0}) # 返回匹配的第一条,除了name,age字段其他都要。返回字典 res = col.find_one({"$gt"{"age":20}}) # 大于20得 # 排序 col.find().sort([("name",pymongo.DESENDING), ("age",ASCENDING)]) # name降序, age升序 # 统计条数 col.find().count() # 分页 col.find().skip(5).limit(10)
查询时可以添加查询条件比较运算,与或非关系,与客户端的条件查询使用方式相同,
更新
文档的更新的操作符号
$inc,对该字段增加指定的值来更新这个数据
$set,更新文档时,这个字段不存在,就新建这个字段
$uset,更新文档,移除该字段
# 更新一条 col.update_one({"name":"tom"},{"$inc":{"age":5}}) # 查询第一个tom,将其年龄增加5 col.update_many("addr":"shanghai", {"$set":{"selery":5000}}) # 更新所有地址为shanghai的selery信息,没有新增 # 替换 col.replace_one({"name":"tom"},{"name":"tom","age":20}) # 替换匹配到的该条文档的信息,除_id全部替换 # 删除 col.delete_one({"name":"tom"}) # 删除匹配的第一条 col.delete_many({"name":"tom"}) # 删除多条 col。delete_many() # 删除所有