• MongoDB创建更新和删除文档


    MongoDB最基础的部分已经看的差不多了,作为数据库来说做的最多的还是对数据库数据的操作。本文将介绍MongoDB中一下三点

        • 向集合中添加新文档
        • 从集合中删除文档
        • 更新现有文档

    插入并保存文档

    插入一条记录

    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    > db.user.insert({username:'aaa',password:'bbb',tel:'123123123'});
    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    { "_id" : ObjectId("51b91edc32b7955cd61dbc8e"), "username" : "aaa", "password" :
     "bbb", "tel" : "123123123" }
    >


    操作为文档增加了一个“_id”,然后保存到了MongoDB中

    > db.user.insert({_id:'12345678',username:'aaa',password:'bbb',tel:'123123123'})
    ;
    > db.user.find();
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    { "_id" : ObjectId("51b91edc32b7955cd61dbc8e"), "username" : "aaa", "password" :
     "bbb", "tel" : "123123123" }
    { "_id" : "12345678", "username" : "aaa", "password" : "bbb", "tel" : "123123123
    " }
    >

    如果我们自己定义了一个_id的话,数据库就不在自己生存,可以看到数据库自己生成的是ObjectId。

    批量插入

    如果要插入多个文档,批量要快一些。批量插入能传递一个由文档构成的数组给数据库

    一次发送多个文档会提高插入数度。一次插入需要建立一个TCP链接。批量提交,会比多次提交数据少建立TCP连接,避免了零碎的请求开销。而且批量提交只会有一个文件头信息,数据不用多次的处理文件头。

    用数组的方式一次插入两条数据

    > db.user.insert([{username:'aaa',password:'bbb',tel:'123123123'},{username:'bbb
    ',password:'ccc',tel:'123123234'}]);
    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    { "_id" : ObjectId("51b91edc32b7955cd61dbc8e"), "username" : "aaa", "password" :
     "bbb", "tel" : "123123123" }
    { "_id" : "12345678", "username" : "aaa", "password" : "bbb", "tel" : "123123123
    " }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc8f"), "username" : "aaa", "password" :
     "bbb", "tel" : "123123123" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "username" : "bbb", "password" :
     "ccc", "tel" : "123123234" }
    >

    插入原理和作用

    当执行插入事,使用的驱动会将数据转换为BSON的形式,将其送入数据库。数据库解析BSON,检验是否有_id,和文档的大小,除此之外,文档不做别的数据验证,简单的将数据存入数据库中。

    ps.大于4M的文档是不能存入数据库中的。

    删除文档

    删除文档用

    > db.user.remove()

    如果remove不传入任何参数,会删除所有文档,但不会删除集合本身,原索引也会保留。

    如果给定参数,只有符合条件的才会删除

    > db.user.remove({username:'aaa'})
    > db.user.find();
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "username" : "bbb", "password" :
     "ccc", "tel" : "123123234" }
    >


    删除速度

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

    更新文档

    文档存入数据库后,就可以用update方法来修改它,update有两个参数一个是查询文档,找出需要更新的文档。一个是修改文档,描述对找到的文档做哪些修改

    更新操作是原子的,若是两个更新同时发生,先到达服务器的先执行。

    文档替换

    更新最简单的就是完全用一个新文档替代匹配文档。比如我们将username为bb的文档替换为如下

    > db.user.update({username:'bbb'},{password:'abc'});
    > db.user.find();
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    >

    我们发现文档结构被替换成了

    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    >

    也就是说这样的替换是直接替换文档,而不是做修改。在大的改动的情况下,使用文档变更可以直接替换文档,但有时候这样却不是我们想要的,我们只是希望修改password而不变动其他的内容

    使用修改器

    通常文档只会有部分要更新。利用原子的修改器,可以用来部分更新。

    $set修改器

    $set用来指定一个键的值,如果这个键不存在,就创建它。下面我们修改username为wangwu的password的值

    > db.user.find();
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "121212", "tel" : "121212" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    > db.user.update({username:'wangwu'},{$set:{password:'abcdef'}});
    > db.user.find();
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
    " : "abcdef", "tel" : "121212" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    >

    $unset修改器

    $unset来删除一个键,比如删除username为wangwu的tel键

    > db.user.update({username:'wangwu'},{$unset:{tel:1}});
    > db.user.find();
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "password" : "abcdef", "username
    " : "wangwu" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    >

    $inc修改器

    $inc用来增加已有的键值,或者在键值不存在时创建。

    现在我们需要一个age的值

    现在给age执行$inc

    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "password" : "abcdef", "username
    " : "wangwu" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    > db.user.update({username:'wangwu'},{$inc:{age:1}});
    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 1, "password" : "abcdef"
    , "username" : "wangwu" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    > db.user.update({username:'wangwu'},{$inc:{age:1}});
    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "password" : "abcdef"
    , "username" : "wangwu" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    >


    这里执行了两次$inc,age第一次创建了一个值为1的键值,然后自加了1.

    $inc键的值必须为数字,如果尝试修改成其他类型就会出现如下错误

    > db.user.update({username:'wangwu'},{$inc:{age:'abc'}});
    Modifier $inc allowed for numbers only
    >


    数组修改器

    数组修改器只能用于数组。

    $push会像已有的数组末尾假如一个元素

    $pop会从头部删除一个元素

    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "password" : "abcdef"
    , "username" : "wangwu" }
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    > db.user.update({username:'wangwu'},{$push:{arr:1}});
    > db.user.find()
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  1 ], "pass
    word" : "abcdef", "username" : "wangwu" }
    > db.user.update({username:'wangwu'},{$push:{arr:2}});
    > db.user.find()
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  1,  2 ], "
    password" : "abcdef", "username" : "wangwu" }
    > db.user.update({username:'wangwu'},{$pop:{arr:2}});
    > db.user.find()
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  1 ], "pass
    word" : "abcdef", "username" : "wangwu" }
    > db.user.update({username:'wangwu'},{$pop:{arr:2}});
    > db.user.find()
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [ ], "passwor
    d" : "abcdef", "username" : "wangwu" }


    数组的定位修改器

    若是数组中多个值,我们只想修改其中的部分值,有两种方法操作数组中的值:通过位置和定位操作符($)

    > db.user.update({username:'wangwu'},{$set:{'arr.1':1}});
    > db.user.find()
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  1,  3,
      4 ], "password" : "a", "username" : "wangwu" }
    > db.user.update({username:'wangwu'},{$set:{'arr.$':1}});
    Cannot apply the positional operator without a corresponding query field contain
    ing an array.
    > db.user.update({'arr.1':1},{$set:{'arr.$':1}});
    > db.user.update({'arr.1':1},{$set:{'arr.$':3}});
    > db.user.find()
    { "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  3,  3,
      4 ], "password" : "a", "username" : "wangwu" }
    >

    使用位置可以直接修改指定位置的数据,使用定位操作符是在查询的时候不知道该位置的时候使用,这个时候需要注意的是查询username的时候,使用$会报出错误。也就是查询出来的值不是数组,所以不能用$来指定

    upsert

    upsert是一个特殊的更新。当没有文档符合更新条件,就会以这个条件创建新的文档。当update的第三个参数设置为true的时候,为upsert模式

    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  3,  3,
      4 ], "password" : "a", "username" : "wangwu" }
    > db.user.update({age:1},{$set:{abc:123}},true)
    > db.user.find()
    { "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  3,  3,
      4 ], "password" : "a", "username" : "wangwu" }
    { "_id" : ObjectId("51ba745f5fdf5d2d7426eb35"), "abc" : 123, "age" : 1 }
    >

    更新多个文档

    默认情况下,更新只能对符合匹配条件的第一个文档操作,要是有多个文档符合条件,其余的文档就没有变化。要使所有的文档都得到更新,可以设置update的第四个参数为true

    返回已经更新的文档

    用getLastError只能获取有限的信息,并不能返回更新的文档。这个可以通过findAndModify来做到。

    安全操作

    MongoDB选中选择不安全的版本作为默认操作,如果需要判断状态,在执行完操作后立即运行getLastError,来检查是否成功。

    如果不考虑安全性的问题,就无序调用getLastError

    把重要的数据用安全的方式操作

    请求和连接

    数据库为MongoDB创建了一个队列,存放这个连接请求。当客户端发送一个请求,会被放到队列的末尾。只有队列中的请求都执行完毕,后续的请求才会执行。每个连接都有独立的队列。

  • 相关阅读:
    easyexcel: The maximum length of cell contents (text) is 32,767 characters
    分库分表情况下添加索引
    如何保证消息顺序执行(Rabbitmq/kafka)
    MySQL Boolean类型的坑
    Redis居然还有比RDB和AOF更强大的持久化方式?
    ThreadLocal的应用场景和注意事项有哪些?
    spring boot 设置tomcat post参数限制
    并发慎用——System.currentTimeMillis()
    Java多线程中static变量的使用
    临时修改session日期格式冲突问题
  • 原文地址:https://www.cnblogs.com/ac1985482/p/3133851.html
Copyright © 2020-2023  润新知