1.mongodb介绍
MongoDB是一种存储文档的非关系型数据库,是无模式的文档型数据库. 所谓的无模式就是第一个文档和第二个文档没有任何关系,每一个document都是独立的.
所谓的文档是一种类似于json的结构,叫BSON(binary json),BSON是一个轻量级的二进制数据格式.已bjson的方式存储到磁盘中.
选择JSON进行改造的原因主要是JSON的通用性及JSON的schemaless的特性。BSON有JSON没有的Date和BinData
每个document大小限制为16M
面向文档的数据库与关系数据库有着显著的区别,面向文档的数据库用一个有组织的文件来存储数据,而不是用行来存储数据,在MongoDB中,一组文档被看作是一个集合,在关系数据库中,许多行的集合被看作是一张表。
MongoDB优势:
读写速度快
模式灵活
高可用
地理位置索引
水平扩展
强一致性
二级索引
劣势:
MongoDB是最像RDBMS的一款nosql数据库
无模式
特点一:所谓的无模式就是第一个文档和第二个文档没有任何关系,每一个document都是独立的.
特点二:在同一个文档可以定义相同的字段名:但是没有意义.比如
{ "name":"小明", "name":"小红" }
2.MongoDB的安装配置
Ubuntu的官网配置:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/
安装配置教程: https://blog.csdn.net/qq_27378621/article/details/80933354
Mongo不能启动:https://blog.csdn.net/qq_20545159/article/details/48653533
MongoDB的默认端口号27017
MongoDB服务器启动命令 net start mongodb
在Ubuntu中使用配置文件启动 mongod -f /etc/mongod.conf
默认情况下用配置文件启动MongoDB,当关闭shell时,MongoDB也会关闭,为了解决这个问题添加--fork参数:
mongod -f /etc/mongod.conf --fork
MongoDB客户端即shell启动命令 mongo
MongoDB服务器重启命令:sudo service mongod restart
配置文件的位置:/etc/mongod.conf
官方建议要关闭大页内存:用于提升MongoDB的性能,具体用到要百度一下
3.MongoDB数据库的连接格式
标准的uri的连接语法:
mongodb://[username:password@]host1[:port1][/[database][?options]]
-
mongodb:// 这是固定的格式,必须要指定。
-
username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库
-
host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。
-
portX 可选的指定端口,如果不填,默认为27017
-
/database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。
-
?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开
例子:
mongodb://root:password@4.5.9.15:27017/
数据库认证
当你登录数据库时,输入show dbs;显示以下页面时
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
证明你没有认证,即没有权限,
有两种方法:
第一种这时候如果你是root用户时,需要use到admin数据中,进行权限认证
db.auth("root","password") #认证成功会返回1
第二种方法
命令行中进行登陆 [mongod@MongoDB ~]$ mongo -uroot -proot admin MongoDB shell version: 3.2.8 connecting to: admin >
4.操作数据库
创建数据库
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库
#查看所有的数据库,新建的数据库不会显示,需要向里边插入一条数据
show databases;
或
show dbs;
MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
注意:在mongodb中数据库和集合你都不需要手动创建,当我们创建文档的时候,如果数据库和集合不存在,它会自动创建
查看数据库
db.serverstatus()查看该服务器的状态。
db.stats()查看当前Mongodb数据库运行状态的命令。
我们来看db.stats,默认显示的文件大小是字节,如果要以GB这样显示,就要这样写db.stats(1024*1024*1024)
下面的例子就是用G来作为单位的。
{ "db" : "test", "collections" : 4.0, "views" : 0.0, "objects" : 68884.0, "avgObjSize" : 2382.189942512049, "dataSize" : 0.15282516553997993, "storageSize" : 0.8786697387695312, "numExtents" : 0.0, "indexes" : 3.0, "indexSize" : 0.011112213134765625, "fsUsedSize" : 2196.860252380371, "fsTotalSize" : 10979.323432922363, "ok" : 1.0, "operationTime" : Timestamp(1562049466, 100), } }
"db" : "test" ,表示当前是针对"test"这个数据库的描述。想要查看其他数据库,可以先运行$ use databasename(e.g $use admiin). "collections" : 3,表示当前数据库有多少个collections.可以通过运行show collections查看当前数据库具体有哪些collection. "objects" : 13,表示当前数据库所有collection总共有多少行数据。显示的数据是一个估计值,并不是非常精确。 "avgObjSize" : 36,表示每行数据是大小,也是估计值,单位是bytes "dataSize" : 468,表示当前数据库所有数据的总大小,不是指占有磁盘大小。单位是G "storageSize" : 13312,表示当前数据库占有磁盘大小,单位是bytes,因为mongodb有预分配空间机制,为了防止当有大量数据插入时对磁盘的压力,因此会事先多分配磁盘空间。 "numExtents" : 3,似乎没有什么真实意义。我弄明白之后再详细补充说明。 "indexes" : 1 ,表示system.indexes表数据行数。 "indexSize" : 8192,表示索引占有磁盘大小。单位是bytes
我们会疑问为什么dataSize会比storageSize,因为从MongoDB3.2开始默认使用wiredtiger存储引擎,会对数据进行压缩。
查看当前服务器下所有的数据库
show databases;或者dbs
查看当前数据库所有的集合
show collections # 或者show tables
查看当前使用的数据库
db.getName(); #或者db
查看当前连接的哪台服务器:
db.getMongo()
删除数据库
db.dropDatabase()
使用数据库
use text
5.操作集合
#创建集合,options表示可选,指定有关内存大小及索引的选项。在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。 db.createCollection(name, options) #删除集合 db.collection.drop() #查看集合 show tables #清空集合 db.col.remove({})
db.log.stats() # 查看数据状态 db.log.dataSize() # 集合中数据的原始大小 db.log.totalIndexSize() # 集合中索引数据的原始大小 db.log.totalSize() # 集合中索引+数据压缩存储之后的大小 db.log.storageSize() # 集合中数据压缩存储的大小
6.操作文档CRUD
文档的插入(insert或save)
save的具体介绍参考下面的更新
1.操作单个文档:插入单个文档操作:db.集合名字.insert(文档) 或者insertOne()
db.student.insert({name:"孙悟空",age:18})
2.插入多个文档:db.集合名字.insertMany([文档一,文档二])
db.student.insertMany([ {name:"猪八戒",age:18}, {name:"唐僧",age:38}, ]) #注意这里是列表
当我们向集合中插入文档时,如果没有给文档指定_id属性则数据库会自动为文档添加_id属性值,该属性作为文档的唯一标识。
查询文档(find)
db.collection.find(query, projection) #query :可选,使用查询操作符指定查询条件 #projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略
>db.text1.find() { "_id" : ObjectId("5d1d737bd444555f80f3946e"), "name" : "小红花" } { "_id" : ObjectId("5d1d9736b7c688d0d8d1f0fa"), "name" : 123 } { "_id" : ObjectId("5d1d9788b7c688d0d8d1f0fb"), "name" : 123 } { "_id" : ObjectId("5d1d9788b7c688d0d8d1f0fc"), "age" : 34 } { "_id" : ObjectId("5d1d9d514323a818198815a9"), "name" : 1 } { "_id" : ObjectId("5d1d9e654323a818198815aa"), "name" : 123, "age" : 23 }
> db.text1.find({},projection={"age":true})#这里只显示_id和age字段,如果你只想显示age,就把_id设为false或0就可以,注意是js的false
{ "_id" : ObjectId("5d1d737bd444555f80f3946e") }
{ "_id" : ObjectId("5d1d9736b7c688d0d8d1f0fa") }
{ "_id" : ObjectId("5d1d9788b7c688d0d8d1f0fb") }
{ "_id" : ObjectId("5d1d9788b7c688d0d8d1f0fc"), "age" : 34 }
{ "_id" : ObjectId("5d1d9d514323a818198815a9") }
{ "_id" : ObjectId("5d1d9e654323a818198815aa"), "age" : 23 }
pretty格式化显示
可以以格式化的方式来显示结果:
如果不加它
db.col.find() #结果: { "_id" : ObjectId("5d1daf264323a818198815ab"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("5d1dd4ab4323a818198815ac"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5d1dd4b94323a818198815ad"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
加上它后:
db.col.find().pretty() #结果 { "_id" : ObjectId("5d1daf264323a818198815ab"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("5d1dd4ab4323a818198815ac"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5d1dd4b94323a818198815ad"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
比较操作符
: 等于 {"age":32}
$eq: 等于
$ne:不等于(not equal) {"age":{$ne:32}}
$gt:大于(greater than)
$lt:小于(less than)
$lte:小于等于(less than equal)
$gte:大于等于(greater than equal)
例子:
#查询在9月份的生产单 db.getCollection('ecords').find({'生产单时间':{$gt:'2019-08-01',$lt:'2019-08-31'}})
逻辑操作符
1.and 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
> db.text1.find({'age':{$ne:23},'name':'小红花'})#查询age不等于23切name等于小红花的
{ "_id" : ObjectId("5d1d737bd444555f80f3946e"), "name" : "小红花" ,'age':33}
2.$or 条件
$or是比较的不同属性
> db.text1.find({ $or:[ {'name':"小红花"}, {'age':23} ] }) #注意是列表中套字典 { "_id" : ObjectId("5d1d737bd444555f80f3946e"), "name" : "小红花" } { "_id" : ObjectId("5d1d9e654323a818198815aa"), "name" : 123, "age" : 23 }
$in
$in是比较的相同的属性,
#查找员工为谢杰奉,杨水林的员工记录 db.getCollection('records').find( {'员工姓名':{$in:['谢杰奉','杨水林'] }} )
$nin
不包含在某个范围,相当于not in
#查看员工姓名不包含谢杰峰或杨水林 db.getCollection('staff_records').find( {'员工姓名':{$nin:['谢杰奉','杨水林'] }} )
$all
满足所有的元素
> db.user.find({hobby:{$all:["足球"] } })
{ "_id" : ObjectId("5ca7a4c4219efd687462f968"), "id" : 4, "name" : "xiaogang", "age" : 34, "hobby" : [ "羽毛球", "篮球", "足球" ] }
> db.user.find({hobby:{$all:["足球","羽毛球"] } })
{ "_id" : ObjectId("5ca7a4c4219efd687462f968"), "id" : 4, "name" : "xiaogang", "age" : 34, "hobby" : [ "羽毛球", "篮球", "足球" ] }
> db.user.find({hobby:{$all:["足球","桌球"] } })
$ not
不满足某个条件,只可用于一个条件查询
# 查看除了谢杰奉,杨水林之外的员工,即 not in db.getCollection('staff_records').find( {'员工姓名':{$not:{$in:['谢杰奉','杨水林']} }} )
$nor
既不也不运算符
not(A or B) --> not A and not B
db.class.find( {age: {$not {$ gt 17} } },{_id :0} ) 匹配年龄小于等于17的文档 注意: $not 一般添加在条件值的前面,对值进行取反
sort排序
在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
db.text1.find().sort({"age":-1}) #按年龄倒叙
元素操作符
1.$type匹配数据类型
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
#返回title为字符串类型的文档 db.col.find({"title" : {$type : 'string'}})
2.$exists
可依据该字段是否存在来筛选数据
db.getCollection('text').find({"color":{$exists:true}}) # 查找有color属性的文档
limit()指定条数
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数
> db.col.find().pretty().limit(1) { "_id" : ObjectId("5d1daf264323a818198815ab"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
Skip()跳过
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
$regx()正则表达式
模糊查询就是像使用mysql中的模糊查询语句一样:
select * from table where xx like yy
分三种情况:
1.包含:
db.getCollection('shops').find({"name":{"$regex":"门店"}})#包含门店二字
2.查询以XXX开头
db.getCollection('shops').find({"name":{"$regex":"^门店"}}) #查询以门店开头的
3.查询以xxx结尾
db.getCollection('shops').find({"name":{"$regex":"门店^"}}) # 查询以门店结尾的
4.忽略大小写
db.getCollection('shops').find({"name":{"$regex":"N","$options":"$i"}}) #忽略其大小写 option的值包含: i(不区分大小写), m(当使用^与$符号模糊匹配时,作用于屏蔽中间的换行符) , x(忽略注释,以#开头 /n结尾), s(允许所有字符包括换行符参与模糊匹配) 对比
$where
$where操作符功能强大且灵活,它可以将JavaScript表达式的字符串或JavaScript函数作为查询语句的一部分。在JavaScri pt表达式和函数中,可以使用this或obj来引用当前操作的文档。JavaScript表达式或函数返回值为true时,才会返回当前的文档。
内嵌文档的查询
详情见该文档https://www.cnblogs.com/sticker0726/articles/11578775.html
文档的更新
更新有:update, save(0,updateOne,updateMany(),replaceOne()这几个方法
我们用的最多的就是update和save()
MongoDB 使用 update() 和 save() 方法来更新和添加集合中的文档,update是一个原子性操作,要么全部成功要么全部失败.
其中update()用于已经存在的文档进行更新,默认更新一条.,save()直接更新一个完整的文档
update()
常见的更新操作符
注意默认情况下会使用新对象来替换旧的对象,如果需要修改指定的属性,而不是替换,就需要使用修改操作符来完成,$set
除了修改操作符外,还有删除操作符$unset,删除某一属性
1.$set
修改字段中指定的值,如果该字段不存在则不会修改
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document>,
collation:<document>,
arrayFilters:[<filterdocument 1>,...]
} ) #query查询语句相当于where #update要更新的字段,相当于set #upsert : 可选,这个参数的意思是,如果不存在update的记录,是否新插入objNew,true为插入,默认是false,文档不存在就不修改. #multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。 #writeConcern :可选,表示是否使用写入策略。
# arrayFilters:若要更新数组中特定元素,则可通过此参数对条件进行筛选(例子见下方)
db.col.update({"title":"MongoDB 教程"},{$set:{"title":"python"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
$set如何更新嵌入式文档
我们来举个例子
db.c.findOne({"name":"toyota"})
>>>>>
{
"_id" : ObjectId("5003be465af21ff428dafbe7"),
"name" : "toyota",
"type" : "suv",
"size" : {
"height" : 10,
"width" : 5,
"length" : 15
}
}
#size 对应的就是嵌入式文档
那么嵌入式文档中的属性该如何修改
db.c.update({'name':'toyota'},{$set:{'size.height':12}})# 对于内嵌文档在使用$set更新时,使用"."连接的方式。
2.$unset
删除操作符,删除某一字段
> db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "chenzhou", "age" : 23 } > db.students.update({name:"chenzhou"},{$unset:{age:1}}) > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "chenzhou" }
3.$min
如果文档中的某个字段的值,小于$min中字段的值,那么,$min中的值就会替代文档中的值
db.getCollection('bookmark').update({"id":"id1},{$min:{"id1":20}}) #如果文档中的id1小于$min中的ID1,那么文档中的id1就会变成20 #结果: { "_id" : ObjectId("5d75bd4fc0ec911dbec89ec7"), "id1" : 20, "id" : "id1" }
4.$max
与$min相反
5.$inc
相当于mysql自增
db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "chenzhou", "age" : 22 } #查询结果显示年龄为22 > db.students.update({name:"chenzhou"},{$inc:{age:5}}) #执行修改,把age增加5 > db.students.find() { "_id" : ObjectId("5030f7ac721e16c4ab180cdb"), "name" : "chenzhou", "age" : 27 } > #查询结果显示年龄为27,修改成功
6.$mul递乘
原理同上
7.$rename
修改字段名
db.getCollection('bookmark').update({"id":55.0},{$rename:{"id":"id1"}}) #将id字段名修改为id1
8.$push
给文档中的数组添加值,如果文档中没有该数组则添加
db.getCollection('article').find({}) >>> { "_id" : ObjectId("5d633c5123641b1253a21ccf"), "_cls" : "Article.TextArticle", "title" : "哈哈", "author" : ObjectId("5d633c5123641b1253a21cce"), "tags" : [ "mongodb", "mongoengine" ], "comments" : [], "content" : "真的太好了,我真的好喜欢" } #-------------------------- # 添加 db.getCollection('article').update({'title':'哈哈'},{$push:{'hobby':'足球'}}) db.getCollection('article').find({}) >>> { "_id" : ObjectId("5d633c5123641b1253a21ccf"), "_cls" : "Article.TextArticle", "title" : "哈哈", "author" : ObjectId("5d633c5123641b1253a21cce"), "tags" : [ "mongodb", "mongoengine" ], "comments" : [], "content" : "真的太好了,我真的好喜欢", "hobby" : [ "足球" ] } #----------------------------------- # 再添加 db.getCollection('article').update({'title':'哈哈'},{$push:{'hobby':'篮球'}}) db.getCollection('article').find({}) >>> { "_id" : ObjectId("5d633c5123641b1253a21ccf"), "_cls" : "Article.TextArticle", "title" : "哈哈", "author" : ObjectId("5d633c5123641b1253a21cce"), "tags" : [ "mongodb", "mongoengine" ], "comments" : [], "content" : "真的太好了,我真的好喜欢", "hobby" : [ "足球", "篮球" ] }
9.$pop
$pop从数组的头或者尾删除数组中的元素,-1是头部,1是尾部
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t3", "t4" ],"type" : "suv" }
#--从数组的尾部删除 1
> db.c.update({"name" : "toyota"},{$pop:{"title":1}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t3" ], "type" : "suv" }
#--从数组的头部 -1
> db.c.update({"name" : "toyota"},{$pop:{"title":-1}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t2", "t3" ], "type" : "suv" }
10.$pull
从数组中删除满足条件的元素
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2", "t3" ],"type" : "suv" }
> db.c.update({"name" : "toyota"},{$pull:{"title":"t2"}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t3" ], "type" : "suv" }
12.$currentDate
这个以后用到再说
db.collection.updateMany() 更新多个文档
db.collection.updateOne() 更新一个文档
findAndmodify
拥有类似事务特性的更新与查询操作.查询到后更新
它是原子性的,会返回符合查询条件的更新后的文档。
一次最多只更新一个文档,也就是条件query条件,且执行sort后的第一个文档.
db.COLLECTION_NAME.findAndModify({
query:{},
update:{},
remove:true|false,
new:true|false,
sort:{},
fields:{},
upsert:true|false
});
query是查询选择器,与findOne的查询选择器相同
update是要更新的值,不能与remove同时出现
remove表示删除符合query条件的文档,不能与update同时出现
new为true:返回更新后的该文档,false:返回更新前的该文档,默认是false
sort:排序条件,与sort函数的参数一致。
fields:投影操作,与find*的第二个参数一致。
upsert:与update的upsert参数一样。
例子:
db.people.findAndModify({
query: { name: "Andy" },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true
})
举一个我想到的使用场景,模型见下图,
{ "_id" : ObjectId("5d89b36c9adefd1c8bcd5af6"), "book_name" : "天使的翅膀", "count" : 23.0, "borrower" : [ { "name" : "alex" } ] }
应用场景:在图书馆我们要借阅一本书,如果这本书的数量大于0就在borrower中添加这个人的名字,并且count-1
db.getCollection('article').findAndModify({ query:{'book_name':'天使的翅膀','count':{$gt:0}}, update:{ $inc:{'count':-1}, $push:{'borrower':{'name':'李白'}} }, new:true #返回更新前的文档 })
结果:
{ "_id" : ObjectId("5d89b36c9adefd1c8bcd5af6"), "book_name" : "天使的翅膀", "count" : 22.0, "borrower" : [ { "name" : "alex" }, { "name" : "李白" } ] }
findoneAnddelte, findoneAndreplace,使用的方法都是差不多的
介绍较为复杂的arrayFilters参数的用法
#例子 { "_id" : ObjectId("5e119c1ce2dfa21e707580cf"), "product_name" : "DE-1300", "color" : [ "red", "white" ] }
题目要求将color中的red,更改为black
db.getCollection('text').update({ "product_name" : "DE-1300"},
{$set:{"color.$[i]":"balck"}},# 修改数据中的元素数据 {arrayFilters:[{"i":{$eq:"red"}}]}) # 筛选数据中元素的条件
结果:
"_id" : ObjectId("5e119c1ce2dfa21e707580cf"), "product_name" : "DE-1300", "color" : [ "balck", "white" ] }
在修改数据元素数据的语句中,$[i]表示数组中元素的位置.如使用$[],则表示数组中所有的元素.例子中的i为自定义变量,用于arrayFilters参数对数组中的元素进行筛选.$[i]也可以指定数组中元素的位置,color.1指数组中第二个位置的元素
save()
save()有更新和插入两个功能,到底是更新还是插入取决于save中有没有_id参数,如果有_id那么save就是更新,如果没有传入_id参数或者_id参数不存在数据库中就是插入.
其中save()方法用新文档来替换文中的旧文档,而不是向update跟新部分字段
>db.col.save({
"_id" : ObjectId("56064f89ade2f21f36b03136"),
"title" : "MongoDB",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "Runoob",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"NoSQL"
],
"likes" : 110
})
文档的删除
remove函数
db.collection.remove( <query>, { justOne: <boolean>, writeConcern: <document> } ) #query :(可选)删除的文档的条件。 #justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。 #writeConcern :(可选)抛出异常的级别。
到底用deleteOne还是用deleteMany取决于justone
remove() 方法 并不会真正释放空间。
需要继续执行 db.repairDatabase() 来回收磁盘空间。
db.collection.remove({}) 这里必须传参默认删除符合条件的所有文档(删除效率低,一个一个的删除),如果要删除第一个符合条件的文档
db.collection.remove({age:18},true)
db.collection.deleteOne()
db.collection.deleteMany()
db.collection.drop() 删除集合,删除效率比remove高,
一般我们不会真的删除一个文档数据,而是在每个文档中加一个属性,比如is_delete,删除时只需要修改这个值就可以了。
批量操作bulkwrite
具体语法为
db.collection.bulkWrite( [ { insertOne : <document> }, { updateOne : <document> }, { updateMany : <document> }, { replaceOne : <document> }, { deleteOne : <document> }, { deleteMany : <document> } ] )
以后用到的时候再查
group分组
MongoDBdb中也有MySQL一样的分组函数group by ,MongoDB有两个一个在aggravate中,另一个是MongoDB的方法,我们先介绍该group方法
但是这个方法有限制,不建议用这个group ,多多使用aggate中的$group
db.getCollection('orders').group({ key:{"note":1}, # 这个key后边跟你要根据哪个键来分组,相当于group by 后边跟的 $reduce:function (curr,result){ return result.total ++ }, # 该属性必须要有,用于分组后你需要的数据,这里标识我需要分组的个数 initial:{"total":0},# 必须要有初始化的数据,一般用于累计计算 cond:{"_id":{$lte:1}} # 条件相当于where finalize:function(result){ result.avg=result.total/2 } # 这个属性表示分组后的结果你要怎么处理,我这里是把结果都除以2 })
必须有
结果:
[ { "note" : "订单已经关闭", "total" : 7.0, "avg" : 3.5 }, { "note" : "出货成功!", "total" : 16.0, "avg" : 8.0 }, { "note" : "订单代付款", "total" : 2.0, "avg" : 1.0 }, { "note" : "订单待付款", "total" : 5.0, "avg" : 2.5 }, { "note" : "订单已付款", "total" : 1.0, "avg" : 0.5 } ]
浙公网安备 33010602011771号