MongoDB的CURD操作分别通过函数insert()、update()、find()、remove()进行

MongoDB文档新增与删除

MongoDB中关于文档的新增与删除比较简单。主要通过insert方法数和remove方法进行。

文档新增

对目标集使用insert方法,可以插入一个文档,如:

db.user.insert({"name":"wangxs"})

若新增的文档没有"_id"键,则会自动添加。db.user.insert({"_id":"1,"name":"wangxs"})

批量插入:传递一个由文档构成的数组(数组由中括号表示[])给insert方法。如:

db.user.insert([{"name":"wangxs"},{"name":"wdh"},{"name":"cxx"}])

批量插入能够减少插入时间,因为一次插入就是一次TCP请求,而批量插入无需处理大量的消息头。

插入的原理

执行插入时,驱动程序会将数据转换成BSON的形式,然后将其送入数据库,数据库接下BSON,检验是否包含"_id"键并且文档不超过4MB,除此之外不做别的数据验证,只是简单的将文档原样存入数据库中。坏处是允许插入无效的数据,好处是可以远离注入式攻击(插入时并不执行代码),使数据库更安全。

可以在启动数据库服务器时使用--objcheck选项,这样服务器就会在插入之前检查文档的有效性(牺牲了速度)。

BSON

BSON:Binary JSON;是轻量的二进制格式,能够将MongoDB的所有文档表示成字节字符串,存在磁盘也是这种格式。同样,返回到客户端的文档也是BSON格式的字符串。驱动会进行解析并呈现。

BSON格式有下面3个主要的优点:更有效的表示数据,减少占用空间;牺牲空间效率,换取更容易的遍历格式;BSON的编码和解码的速度快,提高性能。

删除文档

使用remove方法对目标集进行数据的清除。如:

db.user.remove()

这种方式只会删除user集合的所有文档,而不删除集合本身,原有的索引也会被保留。

指定删除条件:remove函数接收一个文档作为条件参数,只有符合此条件的文档才会被删除,如:db.user.remove({{"age":22}});该命令删除user集合中年龄为22岁的文档。

数据的删除是永久性的,不能撤销也不能恢复。

删除速度:删除文档通常很快,但要清除整个集合,直接删除集合会更快

查找文档

文档查找涉及到一下几个方面:1)使用find或findOne函数和给定条件进行查询;2)使用$条件查询实现范围、集合包含、不等式和其他查询;3)$where子句或javascript进行复杂查询;4)对查询结果进行分页、排序等。

find函数

MongoDB使用find函数来进行查询,第一个参数决定了要返回哪些文档。若不指定查询文档,默认是{},表示匹配集合的全部内容。

例如:>db.user.find() // 将返回user集合的全部内容

向查询文档添加键值对时,意味着限定查找的条件。例如:

>db.user.find({"age":22}) // 查找user集合中年龄为22岁的用户

> db.user.find({"name":"wangdh"}) // 查找user集合中名字为wangdh的用户

向查询文档中添加多个键值对时,表示多条件组合查询(And操作),例如:

>db.user.find({"name":"wangdh","age":22}) //查找user集合中名字为wangdh且年龄为22岁的用户

指定返回的键(节省传输的数据量、解码文档的时间和内存占用)

有时并不需要将文档中的所有键值对都返回,可以通过find函数的第二个参数指定想要返回的键;例如:

>db.user.find({},{"name":1, "age":1}) // 返回_id、name、age三个键(默认返回_id键)。

>db.user.find({},{"_id":0}) // 返回除_id键外的所有键

查询条件

除了精确查询之外,还可以进行范围、OR、取反等复杂的查询。

1)数字和日期

数字和日期经常会有比较大小的操作,即<、<=、>、>=等操作,在MongoDB中,分别对应于:$lt、$lte、$gt、$gte等比较操作符。例如:

>db.user.find({"age":{"$gte":18,"$lte":30}}) //查询年龄在18-30(含)的用户

>start = new Date("01/01/2003")

>db.user.find({"birthday":{"$lt":start}}) // 查询在2003-01-01之前出生的用户

>db.user.find({"age":{"$ne":22}}) // 查询年龄不为22岁的用户、$ne操作符可用于任何数据类型

2)OR查询

MongoDB有两种方式来进行OR查询。$in操作符可以匹配一个键的多个值;$or操作符可以匹配多个键的任意给定值。相比之下$or操作符更通用。

>db.user.find({"age":{"$in":[22,25,30]}}) // 查询年龄为22、25、30的用户

> db.user.find({"age":{"$nin":[22,25,30]}}) // 查询年龄不为22、25、30的用户

>db.user.find({"$or":{"name":"wangdh"},{"age":22}}) // 查找姓名为wangdh或者年龄为22岁的用户

>db.user.find({"$or":{"name":"wangdh"},{"age":{""$in:[22,25,30]}}}) // 查找姓名为wangdh或者年龄为22、25、30岁的用户

3)$not、$mod操作符

$not是元条件句,可以用在其他条件之上,$mod是取模运算

>db.user.find({"num":{"$mod":[5,1]}}) // 返回num键的值除以5余1的文档

>db.user.find({"num":{"$or":{"$mod":[5,1]}}}) // 返回num键的值除以5不余1的文档

特定类型的查询

针对有特别表示的数据进行的查询,如:null

1)null

null不仅匹配自身,即值为null,也匹配不存在(缺少这个键);例如:

>db.user.find({"y":null})

>db.user.find({"y":{"$in":[null], "$exists":true}}) // 仅匹配null值,通过$exists键值为true来判定键已存在

2)正则表达式

正则表达式能够灵活有效的匹配字符串。MongoDB中的正则表达式与javascript的类似。

>db.user.find({"name":/joe/i}) // 匹配姓名为Joe的用户,忽略大小写

3)查询数组

数组可以理解为每个元素都是对应键的值,如:

>db.food.insert({"fruit":["apple","banana","peach"]})

>db.food.find({"fruit":"apple"}) // 该查询会匹配上述插入的文档

4)查询内嵌文档

查询整个文档或只针对其减值对进行查询。使用点表示法查询内嵌的键:

>db.user.find({"name.first":"wang","name.last":"donghong"})

$where查询

比较文档中两个键的值是否相等:

>db.food.find({"$where":function(){

for(var current in this){

for(var other in this){

if(current!=other && this[current]==this[other]){

return true;

}

}

}

return false;

}})

>db.find.find({"$where":"this.x+this.y==10"})

等价于

> db.find.find({"$where":"function(){return this.x+this.y==10;}"})

分页与排序

采用limit、skip和sort来实现限制返回结果的数量、忽略一定数量的结果并排序。

>db.food.find().limit(3) // 限制返回3个文档

>db.food.find().skip(3) // 跳过前3个文档,返回余下的文档。

sort用一个对象作为参数:一组键值对,键对应文档的键名,值代表排序的方向(1表示升序,-1表示降序)。如果指定多个键,则按照键的顺序逐个排序:

>db.user.find().sort({"name":1,"age":-1}) // 按照name升序,age降序

避免使用skip忽略大量结果,因为会变得很慢。

一种分页的思想:先按照某个键进行排序并使用limit限制返回的个数,下一次使用上一次的排序键的最大值作为筛选条件且使用limit,如此反复下去…

更新文档

使用update函数来修改存在数据库中的文档。update有俩个参数:第一个是查询文档,用来找出需要更新的文档,第二个是修改器文档,描述对找到的文档做和修改。

文档替换

使用新的文档来替代匹配到的文档,如:

>db.user.update({"name":"wangdh"},{"age":21,"sex":"男"})

当查询条件匹配到多个文档且第二个参数存在_id键时,会因为插入重复的_id值导致数据库报错。

局部更新:使用修改器

$set修改器:用来指定一个键的值,如果这个键不存在,则创建它,存在则用新指定的值替换该键原来的值,如:

>db.user.update({"name":"wangdh"},{"$set":{"lover":"cxx"}})

$unset修改器可以将指定的键删除掉:

>db.user.update({"name":"wangdh"},{"$unset":{"lover":1}})

$inc修改器:增加已有键的值,不存在时创建

>db.user.update({"name":"wangdh"},{"$inc":{"age":1}}) // 将年龄加1

$inc修改器修改的键的值必须是数字,否则会报错。

数组修改器

只能用在值为数组的键上。

$push修改器:向已有数组的末尾加入一个元素。

>db.blog.post.update({"title":"test"},{"$push":{"comments":{"content":"test content"} }})

$pop修改器:从数组任何一端删除元素,{"$pop":{"key":1}}尾部删除{"$pop":{"key":1}}头部删除。

upset更新:没有记录则插入

通过指定update的第三个参数为true来实现。当有匹配文档时,则进行更新,否则进行插入。

批量更新

通过指定update的第四个参数为true来执行批量更新。当匹配到多个文档且第四个参数为true时,对所有匹配到的文档进行更新操作。

MongoDB学习笔记—03 增删改查操作的更多相关文章

  1. MongoDB学习笔记,基础+增删改查+索引+聚合...

    一 基础了解 对应关系 -> https://docs.mongodb.com/manual/reference/sql-comparison/ database -> database ...

  2. MongoDB学习-->命令行增删改查&JAVA驱动操作Mongodb

    MongoDB 是一个基于分布式文件存储的数据库. 由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关 ...

  3. 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查.目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的.下面我们通过创建一个简单的Web API来管理联系 ...

  4. ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查. 目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的. 下面我们通过创建一个简单的Web API来管理 ...

  5. MyBatis学习之简单增删改查操作、MyBatis存储过程、MyBatis分页、MyBatis一对一、MyBatis一对多

    一.用到的实体类如下: Student.java package com.company.entity; import java.io.Serializable; import java.util.D ...

  6. EF学习笔记——通用增删改查方案

    http://blog.csdn.net/leftfist/article/details/25005307 我刚接触EF未久,还不知道它有什么强大之处,但看上去,EF提供了一般的增删改查功能.以往用 ...

  7. Mybatis学习笔记3 - 增删改查示例

    1.接口定义 package com.mybatis.dao; import com.mybatis.bean.Employee; public interface EmployeeMapper { ...

  8. PHP操作xml学习笔记之增删改查(2)—删、改、查

    xml文件 <?xml version="1.0" encoding="utf-8"?><班级>    <学生>       ...

  9. PHP操作xml学习笔记之增删改查(1)—增加

    xml文件 <?xml version="1.0" encoding="utf-8"?><班级>    <学生>       ...

随机推荐

  1. StaticPagedList

    估计是因为水平原因,之前看别人写的用pagedList分页,老是云里雾里的.下面把自己写的整理一下放在上面.这里的List为对应页面展示的内容.不用查询所有. Action: public Actio ...

  2. JQuery Mobile入门——设置后退按钮文字(转)

    http://www.tuicool.com/articles/AZnYVz JQuery Mobile入门——设置后退按钮文字 时间 2013-01-09 20:24:28  CSDN博客原文  h ...

  3. 开启gpu加速的高性能移动端相框组件!

    通过设置新的css3新属性translateX来代替传统的绝对定位改变left值的动画原理,新属性translateX会开启浏览器自带的gpu硬件加速动画性能,提高流畅度从而提高用户体验, 代码有很详 ...

  4. 第三方登录 QQ 错误码100044(提示 该应用非官方正版应用)

    当你碰到这个问题的时候,不要着急,你的功能已经走通了,代码没有问题. 100044 原因: 1.首先确定你的包名和签名,跟申请第三方平台的是一个.(真心吐槽一下,接盘侠不好当,尤其是没有交接的) 2. ...

  5. 2013 acm 长沙网络赛 G题 素数+枚举 Goldbach

    题目 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3856 先预处理求出两个素数的和与积,然后枚举n-prime和n/pr ...

  6. Phabricator部署手册

    参考:https://secure.phabricator.com/book/phabricator/article/installation_guide/ 概述 phabricator,由faceb ...

  7. 巧妙地用二叉树完成算式计算算法<计算器,二叉树,C++,独辟蹊径>

    #01.引言,我们知道算式计算的问题是栈里面一个非常经典的题目.但是用栈来实现是一个非常麻烦的过程,第一要解决算式判断,是否为符合规则的算式,第二要由中最表达式转化为后缀表达式.这两个部分是栈实现计算 ...

  8. Thrift 2中get用法的详细解析

    Thrift2相比于Thrift 1改动较大,这里不去描述改动的地方,但是它的改动确实比Thrift1方便了很多.但是不能理解的是Thrift2网上的资料和文档相当的少,就以Thrift2操作Hbas ...

  9. IOS中无缓存的图片载入

    在IOS中,我们常用[UIImage imageNamed]方法获取图像,这种方法简便,容易理解.但是有个缺点,就是有缓存.这种方式 传人的图像的就是通过文件名方式文件名.如果,我们内存有限,我们就必 ...

  10. C++链接两个cpp 文件

    我们在编程中,有没有想过,分别写代码,然后把两个cpp,文件合并,两个自身本不能运行的文件,在一起却可以运行(主要牵扯函数调用,一个有声明和调用,另一个定义).那么具体如何实现呢? 跟着我的步骤: 1 ...