数据库的增删改查操作:创建、删除、修改、查询。
一、数据库
1、创建数据库
use databasename
e.g. 创建一个叫 stu 的数据库
use stu
* use实际功能是表示选择使用哪个数据库;当这个数据库不存在时即表示创建该数据库
* 使用use后数据库并不会马上被创建,而是需要插入数据后数据库才会创建
数据库名称规则
1. 原则上是任意满足以下几条的utf-8字符
2. 不能是空字符,不能含有空格' ' 点'.' '/' '\' '\0'
3. 习惯上使用英文小写
4. 长度不超过64字节
5. 不能使用 admin local config 这样的名字
说明:
admin:存储用户
local:存储本地数据
config:存储分片配置信息
db:mongo系统全局变量,代表你当前正在使用的数据库
* db默认为test,如果插入数据即创建test数据库
2、查看数据库
show dbs
3、删除数据库
db.dropDatabase()
删除db所代表的数据库,当前所在的数据库
二、集合
1、集合的创建
方法1:创建空集合
db.createCollection(collection_name)
e.g. 在当前数据库下创建一个名字为class2的集合
db.createCollection("class2")
方法2:当向一个集合中插入文档时,如果该集合不存在则自动创建
db.collectionName.insert()
e.g. 如果class0不存在则会创建class0集合并插入该数据
db.class0.insert({a:1})
集合的命名规则:
1. 不能为空字符串,不能有'\0'
2. 不能以 system.开头,这是系统集合的保留前缀
3. 不能和保留字重复
2、查看数据库中集合
show tables
show collections
3、删除集合
db.collectionName.drop()
e.g. 删除class0集合
db.class0.drop()
4、集合重命名
db.collectionName.renameCollection('new_name')
e.g.
db.class2.renameCollection('class0')
将class2重命名为class0
5、获取集合对象
db.getCollection('collectionName')
e.g. 等同于db.class0.insert({name:'悟空',age:1700})
db.getCollection("class0").insert({name:'悟空',age:1700})
三、文档
mongodb中数据的组织形式:文档
mongodb文档 :以键值对形式组成的类似字典的数据描述形式
键值对组成文档 -----》 类似Python中的字典
mongodb 中文档的数据组织形式为bson格式,类似Python的字典,也是由键值对构成
bson -----》 json -----》 JavaScript
文档中键的命名规则 :
1. utf-8格式字符串
2. 不用有\0,习惯上也不用 . 和 $
3. 一个文档中的键不能重复
4. 以_开头的多位保留键,自定义时一般不以_开头
注意:
* 文档中的键值对是有序的
* mongodb中数据严格区分大小写
文档中的值 : mongodb的支持数据类型
官方查询地址:https://docs.mongodb.com/manual/reference/operator/query/type/
类型 | 值 |
整型 | 整数 |
布尔类型 | true false |
浮点型 | 小数 |
Arrays | 数组类型 [1,2,3] |
Timestamp | 时间戳 |
Object | 内部文档 |
Null | 空值 |
Symbol | 特殊字符 |
String | 字符串 |
Binary data | 二进制字串 |
code | 代码 |
regex | 正则表达式 |
ObjectId | ObjectId子串 |
说明:
ObjectId : 系统自动为每个文档生成的不重复的主键
键名称: _id
值 : ObjectId("5b03b823e64cb5d90e9c8f5c")
注:_id : 当在mongo代表中插入文档时,如果不指定_id则会自动添加这个域,作为主键。
ObjectId的24位16进制数值:
8位 文档创建时间
6位 机器ID
4位 进程ID
6位 计数器
集合中文档的特点:
1. 集合中的文档不一定有相同的域
2. 集合中的文档多少不一定相同
3. 集合中的文档,值的类型不一定相同
集合设计原则:
1. 集合中的文档尽可能描述同一类数据
2. 同一类数据不要过多分散在多个集合中存放
3. 集合中文档的结构层次不宜过多
1、插入文档
db.collectionName.insert()
e.g.
db.class0.insert({name:'Lucy',age:16,sex:'w'})
* 当作为文档插入时键可以不加引号
* 一个集合中的文档是有序的
* _id 为系统自动添加主键,如果自己写_id域则会使用自己写的值。但是该值仍不允许重复。
2、查看插入结果
db.collectionName.find()
e.g.
db.class0.find()
3、插入多条文档
db.collectionName.insert([{},{},{}])
e.g.
db.class0.insert([{'name':'阿花',age:28},{name:'阿红',age:26},{name:'阿彪',age:23}])
4、save插入数据
db.collectionName.save()
e.g.
db.class0.save({_id:2,name:'八戒',age:17,sex:'m'})
* 如果不加_id域时用法同insert()
* 如果使用save插入的时候加了_id,则如果_id值不存在则正常插入,如果该值存在,则修改原来内容
* save无法一次插入多个文档
5、文档的删除
mysql:delete from tableName where ....
mongo:db.collectionName.remove(query,justOne)
db.collectionName.remove(query,justOne)
功能:删除指定的文档
参数:query:筛选要删除的文档,类似where子句(用法同查找操作)
justOne:布尔值
false(默认) 表示删除所有筛选数据
true 则表示只删除第一条复合的文档
e.g.
db.class0.remove({$or:[{age:{$exists:false}},{age:{$gt:100}}]})
e.g.删除第一个复合条件的文档
db.class0.remove({sex:{$exists:false}},true)
e.g.删除集合中所有文档
db.collectionName.remove({})
四、查找操作
mysql : select ... from tableName where ....
mongo : db.collectionName.find(query,field)
db.collectionName.find() ---> select * from tableName
1、find(query,field)
功能 : 查找所有符合条件的文档
参数 : query : 筛选条件 相当于where字句
field : 展示的域 相当于select的展示部分
返回 : 返回所有查找到的内容
query : 以键值对的形式给出筛选条件
field 参数 : 选择要展示的域,传一组键值对
键表示域名
值表示是否显示该域:0 表示不显示
1 表示显示
* 如果某个域给定0 则表示不显示该域,其他的域均显示
如果某个域给定1 则表示显示该域 ,其他的域都不显示
* _id 永远默认为显示,除非设置为0
* 除_id外其他域 必须拥有相同的设置,全为0或者全为1
* 如果不写该参数则表示显示所有域内容
e.g.
db.class0.find({name:'Lily'},{_id:0,name:1,age:1})
2、findOne(query,field)
功能 : 只查找第一条复合条件的文档
参数返回值同find()
e.g.
db.class0.findOne({age:17},{_id:0})
3、进一步的信息筛选
distinct()
功能:查看一个集合中某个域值的覆盖范围
e.g. 查看集合中age域的值都有哪些
db.class0.distinct('age')
pretty()
功能:将查询结果格式化显示
e.g.
db.class0.find().pretty()
limit(n)
功能:查询结果显示前 n条
e.g. 查询结果显示前3个
db.class0.find({},{_id:0}).limit(3)
skip(n)
功能:显示时跳过前n条
e.g. 显示时跳过前三条
db.class0.find({},{_id:0}).skip(3)
count()
功能:对查找结果计数统计
e.g. 统计sex 为 m的文档数量
db.class0.find({sex:'m'},{_id:0}).count()
sort({键:1/-1})
功能:对查找结果排序
1 表示按照升序排列
-1 表示按照降序排列
e.g. 对查找结果按照年龄升序排列
db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1})
4、示例
复合排序 :
e.g. 当第一排序项相同的时候,按照第二排序项排序
db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1,name:-1})
函数的连续使用:
e.g. 获取集合中年龄最小的三个文档
db.class0.find({},{_id:0}).sort({age:1}).limit(3)
五、修改数据
mysql:update tableName set ... where .....
mongo:db.collectionName.update(query,update,upsert,multi)
db.collectionName.update(query,update,upsert,multi)
功能:修改一个文档
参数:query:删选要修改的文档,相当于where子句(用法同查找)
update:将数据更新为什么内容,相当于set操作;
需要配合修改操作符
upsert:bool值
false(默认) 表示如果query的文档不存在则无法修改
true 表示如果query的文档不存在则根据query和update参数插入新的文档
multi:bool值
false(默认) 如果有多条符合筛选条件的文档则只修改第一条
true 则修改所有符合条件的文档
e.g. 将阿红年龄改为24
db.class0.update({name:'阿红'},{$set:{age:24}})
e.g. 如果筛选数据不存在则插入一个新的文档
db.class0.update({name:'阿花'},{$set:{age:18,sex:'w'}},true)
e.g. 可以同时修改多条匹配到的文档
db.class0.update({sex:'w'},{$set:{age:20}},false,true)
操作符 | 含义 | 示例 | 意思 |
$set | 修改一个域的值 增加一个域 | db.class0.update({name:'阿红'},{$set:{sex:'w'}}) | |
$unset | 删除一个域 | db.class0.update({name:'八戒'},{$unset:{sex:0,age:0}}) | 删除文档的sex和age域(后面数字习惯写1,0 都表示删除) |
$rename | 修改一个域的名称 | db.class0.update({},{$rename:{sex:'gender'}},false,true) | 修改所有的sex域为gender |
$setOnInsert | 如果update操作插入新的文档,则补充插入内容 | db.class0.update({name:'阿华'},{$set:{age:21},$setOnInsert:{sex:'m',tel:'123456'}},true) | 如果插入数据则同时插入sex和tel域内容 |
$inc | 加减修改器 | db.class0.update({age:{$lt:18}},{$inc:{age:-2}},false,true) | 年龄减2 * 正数、负数、小数 |
$mul | 乘法修改器 | db.class0.update({name:'阿华'},{$mul:{age:-0.5}}) | * 正数、负数、小数 |
$min | 设定最小值 : 如果筛选的文档指定的域值小于min值则不修改,如果大于min值则改为min值 | db.class0.update({},{$min:{age:19}},false,true) | |
$max | 设置最大值 : 如果筛选的文档指定至于大于max值则不变,如果小于max值则修改为max值 | db.class0.update({},{$max:{age:20}},false,true) | |
数组修改器 | |||
$push | 向数组中添加一项 | db.class1.update({name:"Abby"},{$push:{score:30}}) | |
$pushAll | 向数组中添加多项 | db.class1.update({name:"Jame"},{$pushAll:{score:[10,20]}}) | |
$each | 逐个操作 | db.class1.update({name:"Lily"},{$push:{score:{$each:[10,5]}}}) | 利用each添加多项 |
$position | 选择数据位置进行操作 必须和each合用 | db.class1.update({name:"Lucy"},{$push:{score:{$each:[10,10],$position:1}}}) | |
$sort | 对数组进行排序 必须和each合用
| db.class1.update({name:"Lily"},{$push:{score:{$each:[],$sort:1}}}) | |
$pull | 从数组中删除一个元素 | db.class1.update({name:'Lucy'},{$pull:{score:10}}) | |
$pullAll | 从数组中删除多个元素 | db.class1.update({name:'Jame'},{$pullAll:{score:[10,20]}}) | |
$pop | 弹出数组中的一项 | db.class1.update({name:'Lily'},{$pop:{score:-1}}) | * -1表示弹出数组中的第一项 1 表示弹出最后一项 |
$addToSet | 向数组中插入一个元素,但是该元素不能和其他元素重复 | db.class1.update({name:'Lily'},{$addToSet:{score:66}}) | 如果已经存在66则无法插入,如果不存在则插入66 |
六、补充
1、时间类型
mongo中存储时间的格式 :ISODate
方法1:自动生成当前时间
db.class2.insert({title:'Python入门',date:new Date()})
方法2:生成当前时间
db.class2.insert({title:'Python精通',date:ISODate()})
方法3:将生成时间变为字符串存储
db.class2.insert({title:'Python AI',date:Date()})
ISOData()
功能:指定时间的转换,生成mongo时间类型
参数:如果不加参数则生成当前时间
参数格式
"2018-11-11 11:11:11"
"20180101 11:11:11"
"20181102"
e.g.
db.class2.insert({title:'Python 爬虫',date:ISODate("20180101 11:11:11")})
时间戳获取
e.g.
db.class2.insert({title:'PythonWeb',date:ISODate().valueOf()})
2、null
1. 如果某个域存在却没有值可以设置为null
e.g.
db.class2.insert({title:'Python 秘籍',price:null})
2.表示某个域不存在可以通过null进行匹配
e.g. 可以查找到date不存在的文档
db.class2.find({date:null},{_id:0})
3、Object类型 (值是一个文档)
* 当使用外层文档引用内部文档的时候可以用 . 的方法引用
在使用时需要加上引号
e.g.
db.class2.find({'publication.publisher':'人民教育'},{_id:0})
e.g.
db.class2.update({title:'Python数据'},{$set:{'publication.price':58.8}})
4、数组的下标引用
使用一个数组时,可以使用 .序列下标 的方式使用数组具体的某一项。同样需要用引号
e.g.
db.class1.update({name:'Lily'},{$set:{'score.0':60}})
e.g.
db.class1.find({'score.0':{$gt:90}})
5、文档查找结果的有序性
可以通过[]取查找结果序列的某一项
db.class1.find({},{_id:0})[1]
七、附录:目录