本章会介绍对数据库移入或者移出数据的基本操作
- 向集合添加文档
- 从集合删除文档
- 更新现有的文档
- 为这些操作选择合适的安全级别
添加删除数据库
添加数据库 :use foo 如果存在foo 就use 不存在就创建foo
删除数据库 1 use 数据库名 2 db.dropDatabase()
插入并保存文档
向集合插入文档,并且查询文档 代码 :
db.foo.insert() foo就是集合 如果不存在创建集合foo insert 就是想这个集合添加文档 find 进行查询 返回的数据中的"_id"是mongodb自动添加的 唯一重复的键
可以批量插入 他接受一个文档数组作为参数
db.foo.batchInsert([{"name":"w"},{"name":"d"},{"name":"r"}])
一次发送数十 数百乃至数千个文档会明显提高插入速度 只有将多个文档插入一个集合时 才有用 如果批量插入的过程中插入失败 那么在这个文档之前的所有操作都会成功插入集合中,而这个文档以及之后的所有文档全部插入失败
插入校验
在文档插入时 mongodb只会对数据进行最基本的检查:检查文档的基本机构 没有_id 自动增加一个 检查大小 所有文档都必须小于16M 主流语言的驱动程序都会在数据插入数据库之前做大量的数据校验
删除文档
db.foo.remove() 清空foo集合中的所有数据
可以接受一个查询文档作为参数 删除数据是永久性的 不能撤销 也不能恢复
删除文档通常很快 但是要清空集合 那么使用drop直接删除结合会更快
db.foo.drop()
更新文档
文档插入数据库以后 就可以使用update方法更新他 update有两个参数 一个是查询文档 用于定位需更新的文档 一个是修改器文档 用于说明要对找到的文档进行那些修改
先到先更新 后到的取得胜利
最简单的更新就是用一个新的文档替换匹配文档 适用于大规模的数据迁移
db.foo.insert({"name":"joe","friends":32,"enemies":2})
我们希望将 friends enemies 两个字段移到 relationships子文档 可以在上shell中改变文档的机构 然后用update替换数据库中的当前文档
var joe = db.foo,findOne({"name":"joe"})
joe.relationships = {"friends":joe.friengs,"enemies":joe.enemies}
joe.username = joe.name
delete joe.friengs
delete joe.enemies
delete joe.name
db.foo.update({"name":"joe"},joe)
使用修改器
通常文档只会有一部分要更新 可以使用原子性的更新修改器 指定对文档中的某些字段进行更新 更新修改器 是中特殊的键 用来指定复杂的更新操作 比如修改 增加 删除键 还可能是操作数组或者内嵌文档
$inc 只能操作值是数字的建 这个这个建存在 +或者- 不存在创建 对于更新数据 因果关系 投票 或者其他有变化的数值的地方 很方便
假设要在一个集合中放置网站的分析数据 只要个人访问页面 就增加计数器 可以使用更新奇原子性完成这个增加 每个URL及对应的访问次数都可以如下格式存储文档中
db.foo.insert({"url":"www","pageviews":52})
db.foo.upate({"url":"www"},{"$inc":{"pageviews":1}})
db.foo.find({"url":"www"})
注意 _id的值是不能改变的 使用修改器时
$set 修改器入门
用来指定一个字段的值 如果这个字段不存在 创建它 这对更新模式或者增加用户定义的键来说非常方便
{"name":"joe","age":30,"sex":"male","locarion":"wisconsin"}
想要添加喜欢的书籍进去 可以使用“$set”
db.users.upate(criteria,{"$set":{"favorite book":"War and peace"}})
这样文档中 就有了favorite book这个键了
要是用户觉得喜欢的是另外一本书
db.users.upate(criteria,{"$set":{"favorite book":"Green Eggs and ham"}}) 据说这本书 是用五十个英文词汇 写成的书
$set 甚至可以修改键的类型 用户觉得自己喜欢很多书
db.users.upate(criteria,{"$set":{"favorite book":["ender's Game","cat's cradle"]}})
突然用户不爱读书了 db.users.upate(criteria,{"$unset":{"favorite book":1}})
也可以用这个修改器 来修改内嵌文档 格式
{"title":"A Blog Post","content":"sdeadfe","author":{"name":"joe","email":"joe@esample.com"}}
{"$set":{"author.name":"joe shmoe"}}
数组修改器
有一类很重要的修改器可用于操作数组, 数组是常用且非常有用的数据结构
添加元素 $push 如果数组已经存在 会在末尾添加一个元素 如果不存在就创建一个新的数组
db.foo.update({"title":"A blog post"},{"$push":{"comments":{"name":""joe,"email":"joe@exmple.com","content":"nice post"}}})
在执行一次 就在添加一条
这种$push 使用形式 比较单一 也可以将他应用到比较复杂的数组操作 使用$each 子操作符 可以通过一次$push 添加多个值
{"$push":{"hourly":{"$each":[572,567,231.123]}}} 这样可以将三个元素添加到数组中 如果希望数组的长度是固定的 那么就需要$slice和$push 组合在一起使用
{"$push":{"top10":{"$each":["大苏打","sdww"],"$slice":-10}}} 会限制数组只包含最后加入的10个元素 $slice值 必须是负数 如果添加的元素个数小10 全部添加 大于10 保留最后10个元素
$slice 与 $push配合使用 且 必须使用$each
$push 一次只能为数组添加一个值,与$each结合可以一次添加多个值,和$slice 结合使用 可以限制添加值的个数
将数组避免重复添加
$addToSet 避免重复添加 存在不操作 不存在添加
{"addToSet":{"emails":{"$each":["joe@php.net","joe@example.com","joe@python.org"]}}}
删除元素
有几个从数组删除元素的方法 若把数据看成队列 或者栈 可以用 $pop 从一端删除元素 {"$pop":{"key":1}} 从末尾删除一个元素 {"$pop":{"key":-1}}从头删除一个元素
有时需要特定条件删除元素 不仅仅基于位置 可以使用"$pull"
{"rodo":["dishes","laundry","dry cleaning"]}
update({},{"$pull":{"todo":"laundry"}})
这个修改器 会将匹配到的文档都全部删除 而不是删除一个 对于数组 [1.1.2.1] 执行pull 1 结果[2]
基于位置的数组修改器
有两种方法操作数组中的值 :通过位置 或者定位符$ 数组的下标都以0开头 可以将下标直接作为键来选择元素
数据模型 :
{
"content":"摄师傅",
"comments":[{
"comment":"good post"
"author" : "john"
"votes" : 0
},{
"comment":"i thought it was to short"
"author" : "claire"
"votes" : 3
},{
"comment":"free watches"
"author" : "alice"
"votes" : -1
}]
}
{"$inc":{"comments.0.votes":1}}
很多情况下 我们不预先查询文档就不能知道要修改的数组下标 为了客服这个困难 mongoDB提供了定位操作符"$" 用来定位查询已经匹配的数组元素并进行更新 例如 用户john把名字改成jim
update({"comments.author":"john"},{"$set":{"comments.$author":"Jim"}})
定位符只更新第一个匹配的元素 如果John发表了多条评论 那么他的名字只在第一条评论中改变
upsert 是一种特殊的更新 要是没有找到符合更新条件的文档机会以这个条件和更新文档为基础穿件一个新的文档 如果找到了匹配的文档 这正常更新 upsert非常方便 不必预置集合
update 的第三个参数 设置成true 就是upsert
需要创建文档的同时创建字段并赋值 但是之后的所有更新操作中 这个字段的值不会改变 这就是$setOnInsert的作用
update({},{"$setOnInsert":{"createAt":new Date()}},true)
再次运行这个语句 会匹配到一存在的文档 所以不会再插入文档 因车createAt 这个字段的值 也饿不会改变
返回被更新的文档
findAndModify 这个方法对于操作队列以及执行其他需要进行原子性取值和辅助的操作十分的方便
代码示例:
ps = db.runCommand({'findAndModify':'pocesses','query':{'status':'READY'},'sort':{"priority":-1},'update':{"$set":{"status":"RUNNING"}}} ).value
在findAndModify 中可以使用的字段
- findAndModify 集合名
- query 查询文档
- sort 排序
- update 修改器文档 用于对匹配的文档更新
- remove 布尔型 是否删除文档
- new 布尔型 返回更新前的文档还是更新后的 默认返回更新前的
- fields 文档中需要返回的字段
- upsert 布尔型 true是upsert 默认是false
update和remove 必须有一个
save shell 帮助程序
save 是一个shell函数 如果文档不存在 自动创建文档 存在更新文档 他只有一个参数 文档 要是这个文档中包含_id save会调用upsert 否则会调用insert
var x = db.foo.findOne()
x.unm = 42
db.foo.save(x)
默认情况下 更新只能对符合匹配条件的第一个文档执行操作 要是有多个文档符合条件 只有第一个文档呗更新 其他文档不会有变化 要更新所有匹配的文档 可以将update的第4个参数设置为true
要知道这条update程序 更新了多少文档 db.runCommand({getLastError:1})
返回的值中 n键的值 就是被更新的文档数量
- 使用DOM进行xml文档的crud(增删改查)操作<操作详解>
很多朋友对DOM有感冒,这里我花了一些时间写了一个小小的教程,这个能看懂,会操作了,我相信基于DOM的其它API(如JDOM,DOM4J等)一般不会有什么问题. 后附java代码,也可以下载(可点击这 ...
- mongoDB 文档概念
mongoDB 文档概念 什么是文档 文档是 mongodb 基本的数据组织单元,类似于mysql 中的记录 文档由多个键值对组成,每个键值对表达一个数据项 属于 bson 数据 ps: bson ...
- mongoDB 文档操作_删
mongoDB 文档删除 MySQL对比 mysql delete from table where ... mongo db.collection.deleteOne(query) 删除函数 del ...
- MongoDB文档的基本操作
1. MongoDB的安装方法 (1)下载MongoDB 相应的版本: (2)设置数据文件和日志文件的存放目录: (3)启动MongoDB服务: (4)将MongoDB作为服务启动. 2. Mongo ...
- mongodb文档支持的数据类型
版权声明:转载请标明来源. https://blog.csdn.net/u014285882/article/details/25510377 1. 存储类型 mongodb文档相似于json,但不是 ...
- 【Elasticsearch 7 探索之路】(二)文档的 CRUD 和批量操作
上一篇,我们介绍了什么是 Elasticsearch,它能做什么用以及基本概念(索引 Index.文档 Document.类型 Type)理解.这篇主要对 文档的基本 CRUD 和 倒排索引进行讲解. ...
- Elasticsearch必知必会的干货知识一:ES索引文档的CRUD
若在传统DBMS 关系型数据库中查询海量数据,特别是模糊查询,一般我们都是使用like %查询的值%,但这样会导致无法应用索引,从而形成全表扫描效率低下,即使是在有索引的字段精确值查找,面对海量数 ...
- MongoDB 文档的查询和插入操作
MongoDB是文档型数据库,有一些专门的术语,和关系型DB相似,但也有差异,例如,Collection类似于关系型DB的Table,document类似于row,key/value pair类似于c ...
- MongoDB文档基本操作
一.插入文档 使用insert()或save()方法向集合插入文档 >db.COLLECTION_NAME.insert(document) 详细用法可以参考MongoDB菜鸟教程 二.查找文档 ...
随机推荐
- Linux抓包工具tcpdump命令详解
1.简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中 ...
- 在iBatis中操作Blob数据类型
这里的Blob数据类型指的是保存了文本的blob数据类型 直接读取blob类型存储的文本,可能会出现乱码,所以需要读取完后进行手动转码 这里使用ibatis作为持久层 SELECT urlconten ...
- 习题:过路费(kruskal+并查集+LCA)
过路费 [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...
- Codeforces Round #323 (Div. 2) C 无敌gcd 数学/贪心
C. GCD Table time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- git下载其他人分支的代码
1. 在工作空间,右键,打开Git Bash 2. clone主分支的代码(即下载主分支代码的过程) 执行命令: git clone xxx.git 3. 进入工程目录 cd xxx 4. 切换到 ...
- 模板jinja2常用方法
http://docs.jinkan.org/docs/jinja2/ 摘自 http://www.pythontip.com/blog/post/5455/ 数学运算 +, -, *, ...
- Fence(codeforces 232D)
题意: 对于给定的a[1..n],定义区间[s,t]和[x,y]"匹配"当且仅当下列条件同时满足:1. t-s=y-x,即长度相同.3. t<x或s>y,即两区间没有交 ...
- URL重写IIS7(URL Rewrite Module) 比之前的urlrewrite更方便使用
原文发布时间为:2011-02-24 -- 来源于本人的百度文章 [由搬家工具导入] 微软在IIS7中添加了URL的重写模块,并且免费使用,可以导入.htaccess规则,确实是个不错的选择 URL ...
- 【传输文件】文件传输协议FTP、SFTP和SCP
网络通信协议分层 应用层: HTTP(Hypertext Transfer Protocol 超文本传输协议,显示网页) DNS(Domain Name System) FTP(File Transf ...
- hdu 5952 Counting Cliques 求图中指定大小的团的个数 暴搜
题目链接 题意 给定一个\(n个点,m条边\)的无向图,找出其中大小为\(s\)的完全图个数\((n\leq 100,m\leq 1000,s\leq 10)\). 思路 暴搜. 搜索的时候判断要加进 ...