MongoDB必备知识手册

一、认识之初

1、NoSQL简介

概念:

  • NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

运用:

  • NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

特点:

  • 不支持SQL语法。存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是KV(key-value键值对)形式。
  • NoSQL 的世界中没有一种通用的语言,每种 nosql 数据库都有自己的 api和语法,以及擅长的业务场景

产品种类:

  • Mongodb
  • Redis
  • Hbase hadoop
  • Cassandra hadoop
    … …

2、NoSQL与SQL的比较

  • 适用场景不同:sql数据库适合用于关系特别复杂的数据查询场景,nosql反之
  • “事务”特性的支持:sql对事务的支持非常完善,而nosql基本不支持事务
  • 两者在不断地取长补短,呈现融合趋势

SQL关系型数据库:
在这里插入图片描述
关系型数据库和非关系型数据库:
在这里插入图片描述
在这里插入图片描述

二、NoSQL - MongoDB

1、理解

  • MongoBD是一个由C++语言编写的,介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中,功能最丰富,最像关系型数据库的。是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似于JSON对象,它的字段值可以包含其他文档、数组及文档数组,非常灵活,旨在为WEB应用提供可扩展的高性能数据存储解决方案。
  • MongoDB 是一个基于分布式物理上不在一起,是分开的。例如一个网页里面有html标签,该页面中加载了css样式,图片,还有视频,这些资源中,html,js,css可能在服务器A上面,图片可能在服务器B上面,视频可能在服务器 c 上面。
  • MongoDB支持多种平台,包扩Windows、Linux、MacOS、Solaris等,在官方网站都可找到相应的安装包。(需要注册
  • 随着大数据的不断发展,非关系型数据库已经变得越来越重要,相关的产品也都得到了飞速发展。而其中MongoDB 更是佼佼者,作为高性能开源文档数据库,MongoDB 以敏捷、可扩展和对企业应用友好而著称,因其操作简单、完全免费、源码公开等特点,受到了IT从业人员的青睐,并被广泛部署于实际的生产环境中。
  • 使用MongoDB的公司包括:BAT、360、Foursquare、Craiglist,、迪士尼、SAP、Intuit、EA等。

2、特点

易扩展:

NoSQL数据库种类繁多, 但是⼀个共同的特点都是去掉关系数据库的关系型特性。 数据之间⽆关系, 这样就⾮常容易扩展

⼤数据量, ⾼性能:

NoSQL数据库都具有⾮常⾼的读写性能, 尤其在⼤数据量下, 同样表现优秀。 这得益于它的⽆关系性, 数据库的结构简单

灵活的数据模型:

NoSQL⽆需事先为要存储的数据建⽴字段, 随时可以存储⾃定义的数据格式。 ⽽在关系数据库⾥, 增删字段是⼀件⾮常麻烦的事情。 如果是⾮常⼤数据量的表, 增加字段简直就是⼀个噩梦。

三、安装与配置

MongoDB下载官网

1、windows环境

目前,MongoDB版本都是4.0+。

  1. 选择该版本,安装到指定的磁盘
    安装好后,查看文件内容。
    在这里插入图片描述
    bin文件夹中,要明白的是:1是关于客户端的启动程序,2是关于服务器的启动程序,有一个"d"字母的区别。中间的.cfg文件是关于配置的文件,可以更绑定ip和端口号。
    在这里插入图片描述

  2. 我的电脑—>高级系统设置,配置bin目录到系统环境变量
    在这里插入图片描述

  3. 创建数据库文件的存放位置
    选择一个位置,新建文件夹来存放数据库文件(可以自行创建,也可以参考下面):
    比如C盘,创建文件data\db,同bin目录下。
    在这里插入图片描述

输入指令mongod --dbpath [自己的路径]
我的是mongod --dbpath "C:\Program Files\MongoDB\Server\4.0\data\db"
这段内容的含义是:指定存储位置,且开启服务器。这个不会弹出下一行输入框,说明MongoDB服务器已经成功开启。
在这里插入图片描述
注意:若路径在C盘,需要管理员省份运行终端!否则报错,而直接弹出下一行输入框。

  1. 再次检测是否成功
    输入指定端口网址http://localhost:27017,出现下面一段英文,则说明成功了。启动mongo.exe客户端即可。
    在这里插入图片描述

使用安装包安装:

  • 解压
tar -zxvf mongodb-linux-x86-64-ubuntu1604-3.4.0.tar
  • 移动到/user/local/目录下
sudu mv mongodb-linux-x86-64-ubuntu1604-3.4.0.tar /user/local/mongodb
  • 将可执行文件添加到path路径中(在~/.bashrc中添加)
export PATH="/usr/local/mongo/bin:$PATH"

alias sudo='sudo env PATH=$PATH'

2、Linux环境

# 安装
sudo apt-get install mongodb

# 删除
sudo apt-get --purge remove mongodb mongodb-clients mongodb-server

# 进入数据库
mongo XXX.XXX.XXX.XXX:27017

具体使用,如:启动,配置绑定ip远程连接等等。(选择"数据库"下的"MongoDB")

四、进入MongoDB数据库

具体是windows环境,Linux环境参考上上一个链接。

1.1、命令模式

命令行方式下启动服务进入数据库

(1)开启服务

  1. 新建一个存放MongoDB数据库的文件夹
  2. cd server中的bin目录中 (若已经配置环境变量,则省略该步骤)
  3. 输入mongod.exe --dbpath "[创建的mongodb数据库的位置]"
    (这服务开启部分同上)

(2)重新打开一个终端

  1. cd mongodb的bin目录 (若已经配置环境变量,则省略该步骤)
  2. 输入mongo.exe,即进入到mongodb数据库
    在这里插入图片描述

1.2、本地模式

配置本地Windows MongoDB服务进入数据库

这样,可设置为开机自动启动,通过命令启动与关闭,大大提高效率。

  1. 在bin同级目录新建文件夹log,进入之后新建一个mongodb.log文件
    在这里插入图片描述

  2. 创建mongodb.log文件
    在这里插入图片描述

  3. 复制如下内容(注意路径按照自己配置的路径填写),以管理员模式运行命令提示符进行粘贴运行:
    mongod --bind_ip 0.0.0.0 --logpath "C:\Program Files\MongoDB\Server\4.0\log\mongodb.log" --logappend --dbpath "C:\Program Files\MongoDB\Server\4.0\data\db" --port 27017 --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install
    或者
    mongod.exe -config "C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg" --install
    这里的意思是绑定IP为0.0.0.0(即任意IP均可访问),指定日志路径、数据库路径和端口,指定服务名称。运行命令时,需要cd到exe文件目录下执行。

  4. 结果,直接指令开启服务,无需再建一个cmd来开启服务。
    在这里插入图片描述
    在这里插入图片描述

  5. 输入mongo.exe,即进入到mongodb数据库

安装服务:
见上3序号的内容,两种安装服务方式
启动服务:
net start MongoDB
关闭服务:
net stop MongoDB
移除服务:
cd到bin路径
mongod.exe --remove

1.3、添加密码

自行添加,自己玩可以不添加

> use admin
switched to db admin
> db.addUser('username','password')

连接

# 不选择数据库
mongo 134.567.345.23:27017 -u username -p password
# 选择数据库
mongo 134.567.345.23:27017/database -u username -p password
# 或者
mongo 134.567.345.23:27017/database -u username -p
# 输入密码

1.4、远程连接

在这里插入图片描述
打开:
在这里插入图片描述
更改:
0.0.0.0允许所有ip访问

bindIp: 0.0.0.0

五、MongoDB概念解析

MongoDB将数据存储为一个文档,数据结构由key==>value键值对组成,字段的值可以包含其他文档、数组以及数组文档

SQL术语/概念MongoDB术语/概念解释说明
databasedatabase数据库
tablecollection数据库表 / 集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins表连接/不支持

六、数据类型

1、MongoDB中的数据类型

下面为MongoDB中常用的几种数据类型:

序号数据类型说明
1Object ID文档ID
2String字符串,最常用。必须是有效的UTF-8
3Boolean存储一个bool值,为true或false
4integer整数可以是32位或者是64位,这取决于服务器
5double存储浮点数
6array数组、列表 多个值存储到一个键
7object用于嵌入式的文档,即一个值为一个文档
8null存储null值
9TimeStamp时间戳,表示从1970-1-1到现在的总秒数
10Date存储当前⽇期或时间的UNIX时间格式

注意事项:

  • 文档中的键值对是有顺序
  • 文档中的值,不仅可以是字符串,还可以是其他类型,甚至可以是另一个文档
  • mongodb区分类型和大小写
  • mongodb的主键为_id
  • mongodb的文档的key是不可以有重复的
  • 以_开头的键是保留

2、json和bson类型

JSON:

什么是JSON: 一种被广泛使用的轻量级的数据交换格式,支持现今绝大多数的主流开发语言。
近几年mongodb则采用了类json的数据格式,在json上进行了丰富和增强,使得mongodb可以处理更大的数据类型。
格式:{“key”:“value”}

BSON:

什么是BSON: 一个类json的一种二进制形式存储的数据格式,简称binary json
特性: 轻量性、可遍历性、高效性

一个文档就相当于一个JSON数据结构

七、对于库和集合的操作

操作语句
查看所有的库show dbs / show databases
创建、选择数据库use [数据库名称]
创建集合(创建表)db.createCollection(‘集合名称’)
查看所有集合show collections
删除集合db.[集合名].drop()
删除当前数据库db.dropDatabase()

注意:

  1. 如果选择的数据库不存在,则为创建数据库,存在则为切换
  2. 使用use创建的数据库是看不见的,除非在数据库中创建按集合9表),可以通过db/db.getName()去进行查看当前所在库
  3. 在mongodb数据库里,对于文档、集合的操作,统一用db(代表当前的库)
  4. 严格区分大小写
  5. 退出之前,最好use一下或者db一下,查看自己当前所在库,避免不显示数据库名。

八、文档的添加

1、insert() 添加单条/多条

操作语句实例
插入一条文档db.[集合名].insert(文档)db.myinfo.insert({“name”:“liyuhong”,“age”:“21”})
插入多条文档db.[集合名].insert([文档1,文档2…]) (列表方式存储)db.myinfo.insert([{‘name’:‘mayun’,‘sex’:‘m’},{‘name’:‘liyuhong’,‘sex’:‘m’}])

注意:

  • 如果插入多条没有给数组,则为插入第一条文档
  • key的引号可加可不加,但是如果python操作mongodb,则必须加引号,否则报错

2、insertOne() 单条/ insertMany() 多条

3.2版本后,还有如下用于插入文档的方式(更加语义化,推荐使用)

操作语句
向指定集合中插入一条文档数据db.collection.insertOne( { } )
向指定集合中插入多条文档数据db.collection.insertMany( [ { }, { } ] )

3、save() 添加、修改单条/多条

操作语句实例
插入文档db.collection.save(文档)db.user.save({‘name’:‘lyh’,‘age’:‘18’})
修改文档(其实就是对要修改的文档进行覆盖)db.collection.save({’_id’:(id值),‘key’:‘value’…})db.user.save({ “_id” : ObjectId(“5ce7e28acfef3375fa66636c”), “name” : “li”, “age” : 18})

注意:
数据的添加建议使用insert(),推荐使用insertOne() / insertMany(),而save()主要作为数据的修改,虽然也有数据添加的功能。

九、 查询

1、普通查询

1.1 find()查询所有

格式:

db.[集合名].find(query,{field:1/0...})

参数:

query:           查询筛选条件,相当于mysql的where
field:1 / 0:     对某些field进行返回或者不返回(参数可选)
操作语句例子
find查询所有db.[集合名].find() / db.[集合名].find({})db.myinfo.find()
只对某些field进行显示db.[集合名].find({},{[域名]:1 / true})db.myinfo.find({},{name:1})
只对某些field进行不显示db.[集合名].find({},{[域名]:0 / false})db.myinfo.find({},{name:0})
指定_id不返回db.[集合名].find({},{_id:false})db.myinfo.find({},{_id:false})
错误的写法db.[集合名].find(name:true,sex:false)

注意:

  • _id默认返回,需要单独给_id设置false
  • inclusion和exclusion两种模式不可混用。因为混用无法推断其他key是否应该返回。
  • 不需要查询条件也要使用{}进行占位
  • 1 / 0与true / false 效果一样

1.2 findOne()查询一条

格式:

db.[集合名].findOne(query,{field:1 / 0 ...})

实例:
查询一条文档,返回name域的值,其余都不返回,包括id(默认返回第一条)

db.myinfo.findOne({},{_id:false,name:true})

2、高级查询

2.1 统计数据条数count()

格式:

db.[集合名].find([query].count())

实例:

db.myinfo.find().count()

2.2 pretty展开来查看

格式:

db.[集合名].find([query]).pretty()

实例:

 db.myinfo.find([{"_id" : ObjectId("5cefb46838dad496a7a8c166")}]).pretty()

2.3 条件查询操作符

注意:查询的时候,是否有引号影响查询结果,若插入时域名和域值加了引号,则查询也要加引号,否则查不到值。

符号符号说明实例说明
$gt大于db.[集合名].find({age:{$gt:‘18’}})年龄大于18
$gte大于等于db.myinfo.find({age:{$gt:‘21’}})年龄大于等于21
$lt小于db.myinfo.find({age:{$lt:‘21’}})年龄小于21
$lte小于等于db.myinfo.find({age:{$gt:‘21’}})年龄小于等于21
key:value等于db.myinfo.find({age:‘21’})年龄等于21
_id:ObjectId(id值)使用id查询db.[集合名].find({"_id" : ObjectId(“5cefb5d838dad496a7a8c168”)})根据id查询文档
/值/模糊查询db.[集合名].find({name:/li/})查询name中包含’li’的文档
/^值/以…某个值作为开头db.[集合名].find({name:/^li/})查询name以’li’开头的文档
/值$/以…某个值作为结尾db.[集合名].find({name:/hong$/})查询name以’hong’结尾的文档
$in在…内db.[集合名].find({‘age’:{$in:[‘18’,‘21’]}})查询年龄为18或者21的文档
$nin不在…内db.myinfo.find({“age”:{$nin:[‘21’,‘21’]}})查询年龄不为18或者21的文档
$ne不等于db.myinfo.find({‘age’:{$ne:‘21’}})查询年龄不等于21的文档

2.4 AND查询

格式:

db.[集合名].find({key1:v1,key2:v2 ...})

实例:
查询年龄为21.且name以g结尾的文档

db.myinfo.find({name:/g$/,age:'21'})

查询age大于等于20,且小于25

db.myinfo.find({age:{$gte:'20',$lte:'25'}})

查询age大于等于20,且小于25,名字为liyuhong的文档

db.myinfo.find({age:{$gte:'20',$lte:'25'},name:'liyuhong'})

2.5 OR查询

格式:

db.[集合名].find({$or:[{条件1},{条件2} ...]})

实例:
查询name为liyuhong或mayun的文档

db.myinfo.find({$or:[{name:'liyuhong'},{name:'mayun'}]})

2.6 AND和OR组合使用

格式:

db.[集合名].find({query1,...,$or:[{query1},{query2} ...]})

实例:
查询姓名为liyuhong,年龄为18或者21的文档

db.myinfo.find({name:'liyuhong',$or:[{age:'18'},{age:'21'}]})

2.7 LIMIT取值

格式:
从第0个开始取num条文档

db.[集合名].find().limit(num)

实例:

db.myinfo.find().limit(2)
db.myinfo.find().limit(3).pretty()

2.8 SKIP跳过文档

从第0个开始跳过num条文档
格式:

db.[集合名].find().skip(num)

实例:

# 跳过2条文档
db.myinfo.find().skip(2)

2.9 LIMIT和SKIP混合使用

格式:

db.[集合名].find().skip(num).limit(num)

实例:
跳过两条,再读取2条文档(读取第3、4条文档)

db.myinfo.find().skip(2).limit(2)

2.10 SORT排序

格式:

# 1为升序,-1为降序
db.[集合名].find().sort({key:1/-1})

实例:
按照年龄进行升序和降序

db.myinfo.find().sort({age:-1})

2.11 投影

在查询到的返回结果中, 只选择必要的字段
格式:

db.集合名称.find({},{字段名称:1,...})


参数为字段与值:值为1表示显示, 值为0不显

特殊: 对于_id列默认是显示的, 如果不显示需要明确设置为0

实例:

# 不显示_id,但是显示item.name和age
db.cur.find({},{_id:0,'item.name':1,age:1})

2.12 聚合 - aggregation

聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。

db.集合名称.aggregate({管道:{表达式}})

在这里插入图片描述
在mongodb中,⽂档处理完毕后, 通过管道进⾏下⼀次处理。常用管道如下:

$match: 过滤数据, 只输出符合条件的⽂档
$count: 数据总计
$group: 将集合中的⽂档分组, 可⽤于统计结果
$limit: 限制聚合管道返回的⽂档数
$skip: 跳过指定数量的⽂档, 并返回余下的⽂档
$sort: 将输⼊⽂档排序后输出

$project: 修改输⼊⽂档的结构, 如重命名、 增加、 删除字段、 创建计算结果
$unwind: 将数组类型的字段进⾏拆分

$match (aggregation)
过滤文档,将符合指定条件的文档传递到下一个管道阶段。

$match 原型形式:{ $match:{<query>}}

$match 获取指定查询条件的文档。查询语法与 读操作查询 语法相同; 即 $match不接受 原始聚合表达式

准备数据:

db.articles.insertMany([
    { "name" : "韩立", "score" : 80, "views" : 100 },
    { "name" : "韩立", "score" : 85, "views" : 521 },
    { "name" : "慕沛灵", "score" : 60, "views" : 1000 },
    { "name" : "陈巧倩", "score" : 55, "views" : 5000 },
    { "name" : "董萱儿", "score" : 60, "views" : 50 },
    { "name" : "菡云芝", "score" : 94, "views" : 999 },
    { "name" : "文思月", "score" : 95, "views" : 1000 }])

以下操作使用 $match 执行简单的相等匹配:

db.articles.aggregate(
    [ { $match : { name : "韩立" } } ]
);

以下示例使用 $ match 管道运算符选择要处理的文档,然后将结果通过管道传递给 $group 管道运算符以计算文档计数:

db.articles.aggregate( [
  { $match: { $or: [ { score: { $gt: 70, $lt: 90 } }, { views: { $gte: 1000 } } ] } },
  { $group: { _id: null, count: { $sum: 1 } } }
] );

在聚合管道中,$ match 选择分数大于 70 且小于 90 或 views 大于或等于1000 的文档。然后将这些文档传送到 $group 以执行计数。

$count (aggregation)

准备数据

db.scores.insertMany([
    { "_id" : 1, "subject" : "History", "score" : 88 },
    { "_id" : 2, "subject" : "History", "score" : 92 },
    { "_id" : 3, "subject" : "History", "score" : 97 },
    { "_id" : 4, "subject" : "History", "score" : 71 },
    { "_id" : 5, "subject" : "History", "score" : 79 },
    { "_id" : 6, "subject" : "History", "score" : 83 }]
)

统计分数大于80的人的个数

  1. 找出所有分数大于八十分的人
  2. 统计所有人数
db.scores.aggregate(
  [
    {$match: {score: {$gt: 80}}},
    {$count: "passing_scores"}
  ]
)

$group (aggregation)

按一些指定的表达式对文档进行分组,并为每个不同的分组输出到下一个阶段的文档。输出文档包含一个_id按键包含不同组的字段。输出文档还可以包含存储由分组一些累加器表达式的值来计算字段 $group_id字段。$group没有 责令其输出文档。

$group 有以下原型形式:

{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

group文档

Accumulator Operator(累加操作) (aggregation)

<accumulator> 操作必须一下的操作之一:

名称描述
$avg返回数值的平均值。忽略非数字值。
$first返回每个组的第一个文档中的值。仅在文档按定义的顺序定义时才使用。
$last返回每个组的最后一个文档的值。仅在文档按定义的顺序定义时才使用。
$max返回每个组的最大值。
$min返回每个组的小值。
$sum返回数值的总和。忽略非数字值。
$push返回每个组的表达式值数组。

数据准备:

db.books.insertMany([
    { "_id" : 8751, "title" : "宴会", "author" : "但丁", "copies" : 2 },
    { "_id" : 8752, "title" : "神曲", "author" : "但丁", "copies" : 1 },
    { "_id" : 8645, "title" : "田园诗", "author" : "但丁", "copies" : 2 },
    { "_id" : 7000, "title" : "奥德赛", "author" : "荷马", "copies" : 10 },
    { "_id" : 7020, "title" : "伊利亚特", "author" : "荷马", "copies" : 10 }
    ])

以下聚合操作将书籍集合中的数据转换为按作者分组的标题。

db.books.aggregate(
   [
     { $group : { _id : "$author", books: { $push: "$title" } } }
   ]
)

$limit (aggregation)

db.books.aggregate(
    { $limit : 3 }
);

$skip (aggregation)

db.books.aggregate(
    { $skip : 3 }
);

$sort (aggregation)

db.books.aggregate(
   [
     { $sort : { copies : -1} }
   ]
)

十、修改

1、update() 修改单条 / 多条

结构:

db.[集合名].update(
	<query>,
	<update>,
	{
		upsert:<boolean>,
		multi:<boolean>
	}
)

参数的使用:

query:      update的查询条件,类似于SQL中的where条件
update:    update对象和一些更新的操作符,如:$inc $set
upsert:     可选,如果不存在update的记录,则是否插入。默认是false不插入。
multi:     可选,默认为false,即只更改找到的第一条记录,如果为true则更新全部。

update更新操作符 $set $inc

(1) $set 直接修改
实例:
将name为liyuhong的文档,key为age的域值改为18

db.myinfo.update({name:'liyuhong'},{$set:{age:'18'}})

(2) $inc 累加修改(只可用于数字类型)
将name为liyuhong的文档,key为age的域值累加5

db.myinfo.update({name:'liyuhong'},{$inc:{age:5}})

(3) multi参数的使用(只可用于数字类型)
将所有文档中age的值累加5

db.myinfo.update({},{$inc:{age:5}},{multi:true})

(4) upsert参数的使用
修改name为linjunjie的文档中age的域值为30,如果该记录不存在,则作为新文档插入

db.myinfo.update({name:'linjunjie'},{$set:{age:30}},{upsert:true})

(5) multi和upsert组合使用
将所有的文档中age的值累加5

db.myinfo.update({},{$inc:{age:5}},false,true)

2、updateOne() 单条 / updateMany() 多条

3.2版本以后

# 更新一条数据
db.[集合名].updateOne(query,update,true/false)

#更新多条数据,第三个参数为upsert
db.[集合名].updateMany(query,update,true/false)

3、replaceOne() 替换单条

db.replaceOne(query,update)

# 一对一替换
db.fanren.replaceOne({name:'杰克'},{'name':'艾伦'})

# 注意,不能包含原子操作符,包含原子操作符报错
[thread1] Error: the replace operation document must not contain atomic operators

十一、文档的删除

1、remove() 删除单条/多条

主体结构:

db.[集合名].remove(
	<query>,
	{
			justOne:<boolean>
	}
)

参数说明:

query:           可选,删除文档的条件
justOne:         可选,如果设为true或者1,则至少删除一个文档。默认为false

用法:

操作语句
默认将所有匹配到的文档进行删除db.[集合名].remove({条件})
只删除第一个匹配到的文档db.[集合名].remove({条件},true/1)
只删除第一个匹配到的文档db.[集合名].remove({条件},{justOne:true})

实例:
删除年龄在30到40之间的文档

db.myinfo.remove({age:{$gte:30,$lte:40}})

删除所有文档

db.myinfo.remove({})

2、deleteOne() 单条 / deleteMany() 多条

3.2版本以后:
remove()方法限制已经过时,推荐使用以下方法

# 删除一条文档,不给参数删除第一条
deleteOne({xxx}) 

# 删除多条文档,不给参数则删除所有
deleteMany({xxx},{xxx}...) 

十二、功能符号$

1、比较运算符

符号含义示例
$lt小于{‘age’:{’$lt’:20}}
$gt大于{‘age’:{’$gt’:20}}
$lte小于等于{‘age’:{’$lte’:20}}
$gte大于等于{‘age’:{’$gte’:20}}
$ne不等于{‘age’:{’$ne’:20}}
$in在范围内{‘age’:{’$in’:[20,23]}}
$nin不在范围内{‘age’:{’$nin’:[20,23]}}

$gt的使用,查询年龄大于20的:

db.myinfo.find({'age':{'$gt':20}})

2、逻辑运算符

NameDescription
$and返回与两个子句的条件匹配的所有文档。
$not返回与查询表达式不匹配的文档。
$nor返回无法匹配两个子句的所有文档。
$or返回与任一子句的条件匹配的所有文档。

$and的使用例子

db.fanren.find( { $and: [ { age: { $ne: 20 } }, { age: { $exists: true } } ] } )

and 运算里面可以嵌套 or

db.fanren.find( {
    $and : [
        { $or : [ { age: { $ne: 20 } }, { age: { $exists: true } } ] },
        { $or : [ { tags: { $eq: "B" }}, { age : { $lt : 20 } } ] }
    ]
} )

3、其他功能符号

符号含义示例示例含义
$regex匹配正则表达式{‘name’:{’$regex’:’^l.*’}}name以l开头
$exists属性是否存在{‘name’:{’$exists’:True}}name属性存在
$type类型判断{‘name’:{’$type’:‘str’}}name的类型为str
$mod数字模操作{‘age’:{’$mod’:[5,0]}}年龄模5余0
$text文本查询{‘KaTeX parse error: Expected '}', got 'EOF' at end of input: text':{'search’:‘Kare’}}text类型的属性中包含Kare字符串
$where高级条件查询{’$where’:‘obj.bug_count==obj.get_count’}自身购买数等于获得数

正则表达式$regex的使用:

db.myinfo.find({'name':{'$regex':'l'}})

关于这些操作更详细的用法:
操作-官方文档

十三、用python操作MongoDB数据库

1、安装扩展库且导入pymongo

pip install pymongo

需要pymongo库中的MongoClient类来连接MongoDb。

from pymongo import MongoClient

2、连接远程客户端

一般来说,只需传入MongoDB的IP和端口port即可。
mongodb端口不传,则默认为:27017。

实例:

from pymongo import MongoClient

# 只传入主机
conn = MongoClient('127.0.0.1')

# 给主机和端口
conn = MongoClient(host='127.0.0.1',port=27017)

# 传入连接字符串
conn = MongoClient(host='mongodb://localhost:27017/')

3、连接数据库和集合

连接数据库:

1.conn.[数据库名]

# 选择数据库   
db=conn.test

2.conn[数据库名]

# 或者  
db=conn['test']

连接集合:

数据库中包含很多集合(collection),类似于关系型数据库中的表。
1.collection = db.collection_name

collection = db.student

2.collection = db[collection_name]

# 连接student集合
collection = db['student']

4、插入数据

MongoDB 中,每条数据其实都有一个_id属性来唯一标识。如果没有显式指明该属性, MongoDB 会自动产生一个ObjectId类型的_id属性。insert()方法会在执行后返回_id值。

(1)插入一条文档

每个文档为一个字典数据。
db.[集合名].insert({文档})

实例:

# 插入一条文档
result = db.myinfo.insert({'name':'liyuhong','age':21,'hobby':'play game'})
print(result)

# 结果
5932a68615c2606814c91f3d

(2)插入多条文档
多个文档(字典数据)包含在一个列表中表示
db.[集合名].insert([{文档1},{文档2}...])

实例:

# 插入多条文档
result = db.myinfo.insert([{'name':'mayun','hobby':'speaking'},{'name':'zhoujielun','hobby':'singing'}])
print(result)

# 结果
[ObjectId('5932a80115c2606a59e8a048'), ObjectId('5932a80115c2606a59e8a049')]

(3). 更新:官方已经不推荐使用insert()方法,有两个方法可以分别单条和多条插入文档。(建议在3.x以上版本使用的插入方法。)

插入一条文档
insert_one({文档})
插入多条文档
insert_many([{文档1},{文档2}...])
实例:

# 插入一条文档
result = db.myinfo.insert({'name':'liyuhong','age':21,'hobby':'play game'})
print(result)
print(result.inserted_id)

# 结果
<pymongo.results.InsertOneResult object at 0x10d68b558>
5932ab0f15c2606f0c1cf6c5

# 插入多条文档
result = db.myinfo.insert_many([{'name':'mayun','hobby':'speaking'},{'name':'zhoujielun','hobby':'singing'}])
print(result)
print(result.inserted_ids)

# 结果
<pymongo.results.InsertManyResult object at 0x101dea558>
[ObjectId('5932abf415c2607083d3b2ac'), ObjectId('5932abf415c2607083d3b2ad')]

(4). 获取ID:
每条数据其实都有一个_id属性来唯一表示。如果不指明该_id,则会自动产生一个ObjectId类型的_id属性。insert()方法会在执行后,返回该_id值。

单条文档id:
.inserted_id
多条文档id:
.inserted_ids

5、查询文档

(1) 查询所有(结果生成器)
db.[集合名].find()

返回结果是 Cursor 类型,它相当于一个生成器,可以通过遍历去获取所有的结果,其中每个结果都是字典类型。

实例:

# 查询所有
result = db.myinfo.find()
print(result) 返回结果类似一个迭代器,可以使用next方法取值
for i in result:
	print(i)
	
# 结果
<pymongo.cursor.Cursor object at 0x1032d5128>
{'_id': ObjectId('593278c115c2602667ec6bae'),  'name': 'liyuhong'}

普通查询:
db.[集合名].find({query})

实例:

#带条件查询
result = db.myinfo.find({'name':'liyuhong'})
print(next(result))

# 结果
<pymongo.cursor.Cursor object at 0x1032d5128>
{'_id': ObjectId('593278c115c2602667ec6bae'),  'name': 'liyuhong'}

(2) 查询一条文档(结果为单个结果)
db.[集合名].find_one({query})
如果查询结果不存在,则会返回 None。

实例:

result = db.myinfo.find_one({'name':'liyuhong'})
print(type(result))
print(result)

<class 'dict'>
{'_id': ObjectId('5932a80115c2606a59e8a049'), 'name': 'liyuhong'}

(3) 根据Id来查询
需要导入ObjectId方法

from bson.objectid import objectId

# 按照Id进行查询
result = db.myinfo.find_one({"_id":ObjectId("5cebda671a8f4a314762160f")})
print(result)

{'_id': ObjectId('5932a80115c2606a59e8a049'), 'name': 'liyuhong'}

(4) 逻辑查询:
db.[集合名].find({query})

实例:
逻辑运算符:$gt

#带条件查询
result = db.myinfo.find({'age':{'$gt':20}})
print(next(result))

# 结果
<pymongo.cursor.Cursor object at 0x1032d5128>
{'_id': ObjectId('593278c115c2602667ec6bae'),  'name': 'liyuhong'}

(5) 模糊查询
db.[集合名].find({query})
实例:

import re
result = db.myinfo.find({'name':re.compile('l')})
result = db.myinfo.find({'name':{'$regex':'l'}})
print(next(result))

这里使用 $regex 来指定正则匹配

6、sort、limit、count、skip的使用

(1) sort排序
排序时,我们可以直接调用 sort 方法,并在其中传入排序的字段及升降序标志。

db.[集合名].find(query).sort('key',1/-1)
1和-1代表升序或降序,或传入字段,pymongo.ASCENDING,即:
db.[集合名].find(query).sort('key',pymongo.ASCENDING/DESCENDING)

实例:

result = db.myinfo.find().sort('age',1)
for i in result:
	print(i)

(2)limit取值
使用limit指定要取的结果个数

db.[集合名].find(query).limit(num)

实例:
取出年龄最大的一条文档

# limit
result = db.myinfo.find().sort('age',-1).limit(1)
print(result)

(3)count计数
要统计查询结果有多少条数据,可以调用 count 方法。

db.[集合名].find(query).count()
返回符合条件的数据条数

(4)skip跳过、偏移
需要取中间某几个元素,这时可以利用 skip 方法偏移几个位置,比如偏移 2,就代表忽略前两个元素,得到第 3 个及以后的元素

db.[集合名].find().skip(num)
注意:
在数据量非常庞大的时候,比如在查询千万、亿级别的数据库时,最好不要使用大的偏移量,因为这样很可能导致内存溢出。此时可以使用类似如下操作来查询:

from bson.objectid import ObjectId
collection.find({'_id': {'$gt': ObjectId('593278c815c2602678bb2b8d')}})

7、update修改

对原数据进行修改,或者增加,或者数据值的增加

update方法其实是官方不推荐使用的方法,在这里分别使用udate_one和update_many方法
(1) update
更新删除原来其他字段:
db.[集合名].update({条件},{'$set':{替换内容}})
更新不影响其他字段:
db.[集合名].update({条件},{替换内容})
原值增加指定的值:
db.[集合名].update({条件},{'$inc':{指定值}})

实例1:

db.myinfo.update({'name':'mayun'},{'$set':{'age':40}})
#  {'ok': 1, 'nModified': 1, 'n': 1, 'updatedExisting': True}
# ok表示执行成功,nModified代表影响的数据条数

实例2:

condition = {'age': {'$gt': 20}}
result = collection.update_one(condition, {'$inc': {'age': 1}})
print(result)
print(result.matched_count, result.modified_count)

# 结果
<pymongo.results.UpdateResult object at 0x10b8874c8>
1 1

(2)update_one第一条符合的数据进行更新
db.[集合名].update_one({条件}, {'$set': {更新的数据}})
例子:

condition = {'name': 'Li'}
student = collection.find_one(condition)
student['age'] = 22
result = collection.update_one(condition, {'$set': student})
print(result)
print(result.matched_count, result.modified_count)

第 2 个参数不能再直接传入修改后的字典,而是需要使用 {’$set’: student} 这样的形式,其返回结果是 UpdateResult 类型。然后分别调用 matched_count 和 modified_count 属性,可以获得匹配的数据条数和影响的数据条数。

结果:

<pymongo.results.UpdateResult object at 0x10d17b678>
1 0

(3)update_many将所有符合条件的数据都进行更新
db.[集合名].update_many({条件}, {'$set': {更新的数据}})
实例:

condition = {'age': {'$gt': 20}}
result = collection.update_many(condition, {'$inc': {'age': 1}})
print(result)
print(result.matched_count, result.modified_count)

<pymongo.results.UpdateResult object at 0x10c6384c8>
3 3

匹配结果不止一条,所有结果都会更新。

(4)获取匹配数据的条数和受影响的数据跳数
.matched_count 匹配数据条数
.modified_count 受影响数条数

8、remove修改

(1) 删除
db.[集合名].remove({query})

删除name为zhoujielun的文档:

db.myinfo.remove({'name':'zhoujielun'})

# 结果
{'ok': 1, 'n': 1}

(2) 全部删除
db.[集合名].remove()

(3) 3.x以上使用,官方建议使用的方法:
删除第一个符合条件的文档
delete_one({query})
实例:

result = db.myinfo.delete_one({'name':'mayun'})
print(result)
print(result.deleted_count)

# 结果
<pymongo.results.DeleteResult object at 0x10e6ba4c8>
1

删除所有符合条件的文档
delete_many({query})
实例:

result = db.myinfo.delete_many({'age':{'$lt':25}})
print(result)
print(result.deleted_count)

# 结果
<pymongo.results.DeleteResult object at 0x10e6ba4c8>
4

返回结果都是 DeleteResult 类型

(4) 获得删除文档条数
.delete_count

9、关闭连接

conn.close()

10、其他操作

另外,PyMongo 还提供了一些组合方法,如 find_one_and_delete、find_one_and_replace 和 find_one_and_update,它们分别用于查找后删除、替换和更新操作,其使用方法与上述方法基本一致。

另外,我们还可以对索引进行操作,相关方法有 create_index、create_indexes 和 drop_index 等。
可见其他CRUD操作官方文档
还有该库的其他使用操作
pymongo库的其他操作

十四、参考文档

MongoDB安装下载官网
MongoDB官方文档(总)
MongoDB官方文档(核心)
MongoDB中文文档
静览的个人站点
菜鸟中文文档
其他CRUD操作官方文档
pymongo库的其他操作
功能符号$-官方文档

十五、更新时间

第一次更新 2020.4.26
第二次更新 2020.6.17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值