zoukankan      html  css  js  c++  java
  • MongoDB:文档增删改查

    Document文档

    在MongoDB中文档是指多个键及其关联的值有序地放置在一起就是文档,其实指的就是数据。

    MongoDB中的文档地数据结构和JSON基本一样,所有存储在集合中地数据都是BSON。

    新增文档

    insert

    此方法是插入文档最常用的方法,可以插入单条或多条文档。

    语法格式:

    db.collection.insert(
    <document or documents>,
    {
    	writeConcern:<document>,
    	ordered:<boolean>
    }
    )
    

    参数说明:

    document or documents:一条文档或多条文档

    • 一条:{doc}
    • 多条:[{doc1},{doc2}...]

    writeConcern:可选参数,表示是否使用写入策略,该策略较为复杂,这里暂不讨论

    ordered:是否为有序插入,默认为true

    • true:文档中有一个发生错误,mongodb将不再继续插入后续文档
    • false:当文档有一个发生错误,不会影响后续文档地插入
    db.user.insert(
    [{ 'name':'wj','age':23},{'name':'zhangsan','age':20}]
    )
    

    image-20210110165048522

    save

    save也可以插入一条或多条文档,但是insert方法插入主键相同的文档时会报错,而使用save方法插入主键相同的文档时则会覆盖原文档。

    db.collection.save(
    <document or documents >,
    {
    	writeConcern:<document>
    }
    )
    

    insertOne

    insertOne只能插入一条文档,如果使用该方法插入多条文档,则mongodb只会新增第一条文档。

    db.collection.insertOne(
    <document>,
    {
    	writeConcern:<document>
    }
    )
    

    insertMany

    该方法可以插入多个文档,语法与insert方法一样,插入成功后,会返回插入文档的主键。

    image-20210110165645134

    注意,使用insertMany插入单条文档,也必须用中括号括起来,否则报错。

    image-20210110170041454

    变量定义和使用

    test_user=({ 'name':'wj','age':23})
    db.user.insert(test_user)
    test_user2=([{ 'name':'wj','age':23},{ 'name':'wj2','age':24}])
    db.user.insertMany(test_user2)
    

    image-20210110170615689

    查询文档

    find

    语法格式:

    db.collection.find(<query>,<projection>);
    

    参数说明:

    • 如果不指定参数(参数为空,则查询该集合中所有文档)
    • query:查询条件
    • projection:该参数可以指定查询结果中需要显示的字段,设置为1,表示显示,为0,则不显示。"_id"字段默认显示。当设置"_id"为1时,其他字段必须为1,否则报错。

    image-20210110172614076

    查询name等于zhangsan,age等于20的文档:

    db.user.find({'name':'zhangsan','age':20})
    

    image-20210110172829459

    比较操作符

    • 小于 $lt
    • 小于等于 $lte
    • 大于 $gt
    • 大于等于 $gte
    • 不等于$ne
    • 等于 $eq
    • 包含 $in
    • 不包含 $nin

    查询age小于22的文档

    db.user.find({'age':{'$lt':22}})
    

    查询age大于等于22的文档

    db.user.find({'age':{'$gte':22}})
    

    查询age不等于23的文档:

    db.user.find({'age':{'$ne':23}})
    

    image-20210110173337445

    查询name值为wj或为zhangsan的文档:

    db.user.find({'name':{'$in':['wj','zhangsan']}})
    

    字母比较:

    按照字母顺序比较:查询name第一个字符比x小的文档

    db.user.find({'name':{'$lt':'x'}})
    

    image-20210110173530215

    逻辑操作符

    总共4种,不过多介绍:$and,$nor,$or,$not

    查询name不是wj的文档:

    db.user.find({'name':{'$not':{'$eq':'wj'}}})
    

    findOne

    查询符合条件的第一个文档(自然排序),参数与find方法一样

    db.user.findOne({'name':{'$lt':'x'}})
    

    image-20210110173832597

    pretty格式化

    使用pretty()方法可以格式化查询返回结果,知道有这一个方法就好,我的查询器默认已经格式化了。

    findOne()默认会格式化返回结果,所以无需加上pretty()。

    db.collection.find().pretty();
    

    复杂查询条件

    并列条件:查询age大于等于22,小于等于24的文档

    db.user.find({'age':{'$gte':22, '$lte':24}})
    

    或者条件:查询age大于等于22、小于等于24,或者name等于zhangsan的文档

    对于这种,语法格式如下:

    # db.collection.find({'$or':[{},{}...]})
    
    db.user.find({'$or':
        [
            {'name':'zhangsan'}
            ,{'age':{'$gte':22, '$lte':24}}
        ]
    })
    

    $type查询

    根据集合中某个属性的类型查询对应的数据,使用$type指定属性类型

    例如:查询name属性为字符串的文档

    db.user.find({'name':{'$type':'string'}})
    

    在mongodb中,数字类型默认都是double

    db.user.find({'age':{'$type':'double'}})
    

    image-20210110175917040

    $type有效值如下

    type number Alias
    Double 1 double
    String 2 string
    Object 3 object
    Array 4 array
    Binary data 5 binData
    Undefined 6 undefined
    ObjectId 7 objectId
    Boolean 8 bool
    Date 9 date
    Null 10 null
    Regular Expression 11 regex
    DBPointer 12 dbPoint
    JavaScript 13 javascript
    Symbol 14 symbol
    JavaScript(with scope) 15 javascriptWithScope
    32-bit integer 16 int
    Timestamp 17 timestamp
    64-bit integer 18 long
    Decimal128 19 decimal

    正则查询

    简写

    语法:

    db.collection.find({field:/pattern/})
    

    查询name中以z开头的文档

    db.user.find({'name':/^z/})
    

    查询name中以n结尾的文档:

    db.user.find({'name':/n$/})
    

    查询name中以z开头、以n结尾的文档(.* 意为多个任意字符)

    db.user.find({'name':/^z.*n$/})
    

    查询name中包含w字符的文档

    db.user.find({'name':/w/})
    

    查询name中包含w字符(忽略大小写)

    db.user.find({'name':/w/i})
    

    差不多了解以上的正则在实际开发中就够用了,那些需要邮箱正则、手机号正则的场景,为什么不在插入数据之前就做处理呢?

    全写

    语法:

    db.collection.find({field:{$regex:/pattern/,$options:'<options>'}})
    db.collection.find({field:{$regex:/pattern/<options>}})
    

    部分操作符也支持正则表达式

    例如:查询name以z开头,或以n结尾的文档

    db.user.find({'name':{'$in':[/^z/,/n$/]}})
    

    image-20210110183333014

    查询name不以z开头的文档

    db.user.find({'name':{'$not':/^z/}})
    

    分页查询

    结合limit()和skip()方法完成分页

    limit:限制多少条返回

    skip:跳过前多少条,并返回

    查询第一页数据,一页三条(查询三条,跳过零条)

    db.user.find().limit(3).skip(0);
    db.user.find().limit(3);
    

    查询第二页数据,一页三条(查询三条,跳过三条)

    db.user.find().limit(3).skip(3);
    

    不跳过任何数据,只查询前三条

    db.user.find().limit(3);
    

    跳过前三条数据,查询剩余所有数据

    db.user.find().skip(3);
    

    有点像mysql的limit n,m 跳过n行查询m行

    排序查询

    使用sort()方法即可排序

    # age列的升序
    db.user.find().sort({'age':1});
    # age列的降序
    db.user.find().sort({'age':-1});
    # 先age升序,再name降序
    db.user.find().sort({'age':1,'name':-1});
    

    更新文档

    mongodb主要通过save(覆盖)和update(修改)来更新文档。

    save

    save的作用是保存文档,如果文档存在则覆盖,不存在则插入。save对文档的存在判断标准是"_id"是否存在。所以如果想用save去更新文档,则必须带上该字段,且该字段在集合中已经存在。

    db.user.save({"_id" : ObjectId("5ffac1b0a1761355478cf855"),'name':'lisi','age':19});
    

    image-20210110185945394

    使用save,如果文档不存在并新增成功,则nUpserted为1,如果存在并修改成功,则nModified为1

    update

    该方法可以通过特定条件来更新一个或多个文档。

    语法格式(其实后面可以携带更多参数,这里仅简单介绍基本用法):

    db.collection.update(<query>,<update>);
    

    参数说明:

    • query 更新文档的筛选条件
    • update 更新的字段和字段值

    覆盖修改

    把name等于wj的文档,变为age等于23(注意,update默认情况下只覆盖匹配到的第一条文档)

    db.user.update({'name':'wj'},{'age':23})
    

    image-20210110191440806

    上图为覆盖后的结果,name字段丢失了,是因为没有写name字段,直接用{'age':23}覆盖了原来的文档

    表达式更新

    $set

    把name等于wj的文档的age修改为25(这里也修改匹配到的第一条文档)

    db.user.update({'name':'wj'},{'$set':{'age':25}})
    

    这里$set的字段,如果字段存在,则修改字段,如果不存在,则添加字段

    $inc

    将字段增加指定的值

    把name等于wj的文档的age增加10

    db.user.update({'name':'wj'},{'$inc':{'age':10}})
    
    $unset

    把对应的字段删除

    把name等于wj的文档的age删除

    #age字段的值任意写,这里只是一个占位标记
    db.user.update({'name':'wj'},{'$unset':{'age':1}})
    
    $push

    这里先给name等于wj的文档添加一个字段courses课程,该字段是一个数组

    db.user.update({'name':'wj'},{'$set':{'courses':['springboot','springcloud']}})
    

    image-20210110192908650

    现在我想向courses字段中添加一个元素docker

    db.user.update({'name':'wj'},{'$push':{'courses':'docker'}})
    

    image-20210110193150577

    注意:以下的写法不是添加多个元素,而是往courses字段中添加了一个数组,所以push只能往数组中添加一个元素(无论是该元素数组还是其他)

    db.user.update({'name':'wj'},{'$push':{'courses':['jenkins','harbor']}})
    

    image-20210110193311978

    如果push的字段不存在,则会新增一个字段,将元素放在数组中

    db.user.update({'name':'wj'},{'$push':{'course':['springboot','springcloud']}})
    

    image-20210110193719342

    $addToSet

    与push类似,该表达式也会向数组中添加元素,如果该元素存在,则不添加否则添加进入数组。

    元素的匹配大小写敏感。

    db.user.update({'name':'wj'},{'$addToSet':{'courses':'springboot2'}})
    
    $pop

    出栈(删除出来的数据),与push(压栈)相反

    #删除courses数组的最后一个元素
    db.user.update({'name':'wj'},{'$pop':{'courses':1}})
    #删除courses数组的第一个元素
    db.user.update({'name':'wj'},{'$pop':{'courses':-1}})
    
    $pull

    推(删除指定元素)

    #删除courses数组中所有名称为docker的元素
    db.user.update({'name':'wj'},{'$pull':{'courses':'docker'}})
    
    $pullAll

    推(删除多个指定元素)

    db.user.update({'name':'wj'},{'$pullAll':{'courses':['docker','springcloud']}})
    

    执行前:

    image-20210110195451844

    执行后:

    image-20210110195525385

    $rename

    修改字段名

    # 将name=wj的文档中,字段名从name修改为user_name
    db.user.update({'name':'wj'},{'$rename':{'name':'user_name'}})
    

    upset和multi

    db.collection.update(<query>,<update>,<upset:boolean>,<multi:boolean>);
    

    对于update方法,还有两个参数可以选择,upset和multi

    • upset:默认为false,为true时,则表示在更新条件没有匹配时,会插入此文档,为false则不插入。
    • multi:默认为false,为true时,会更新所有匹配到的文档,为false,则会更新匹配到的第1个文档。
    #将所有name=wj的文档的age修改为25
    db.user.update({'name':'wj'},{'$set':{'age':25}},false,true)
    #  db.user.update({'name':'wj'},{'age':23},false,true) 该写法错误,多行操作不支持覆盖修改
    

    删除文档

    remove(不推荐)

    删除所有age大于等于28的文档

    db.user.remove({'age':{'$gte':28}});
    

    删除第一条age大于等于20的文档

    db.user.remove({'age':{'$gte':20}},true);
    

    deleteOne

    该方法只能删除匹配到的第一个文档

    删除第一个age大于等于28的文档

    db.user.deleteOne({'age':{'$gte':28}});
    

    deleteMany

    一次性删除所有匹配到的文档

    删除所有age大于等于28的文档

    db.user.deleteMany({'age':{'$gte':28}});
    
  • 相关阅读:
    eclipse如何卸载adt插件
    Android中的Toast.LENGTH_SHORT
    Frogger
    - Oil Deposits 深搜,就是所谓的dfs
    Aggressive cows
    Phone List
    Word Amalgamation
    Street Numbers
    Charm Bracelet——背包问题
    函数参考
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/14259401.html
Copyright © 2011-2022 走看看