• MongoDB


     参考博客:https://www.cnblogs.com/xiao987334176/articles/9635269.html

    一、MongoDB初识

    什么是MongoDB

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

    MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

    官方给出了以上的解释,那么综上所述,马德 F U C K ! 有效信息太少了(完全没用)

    那么让我来用人类的语言讲述一下MongoDB吧

    它和我们使用的关系型数据库最大的区别就是约束性,可以说文件型数据库几乎不存在约束性,理论上没有主外键约束,没有存储的数据类型约束等等

    关系型数据库中有一个 "表" 的概念,有 "字段" 的概念,有 "数据条目" 的概念

    MongoDB中也同样有以上的概念,但是名称发生了一些变化,严格意义上来说,两者的概念即为相似,但又有些出入,不过无所谓,我们就当是以上概念就好啦

    光说的话,还是有点儿模糊,就让我们来做一个小例子,进行一个对比吧

    下面我们做一张表:

    这是我们用关系型数据库做的一张很简单的User表对吧

    接下来我们再看一下MongoDB的数据结构:

    User = [{
        "name": "武大郎",
        "age": 18,
        "gender": ""
    }, {
        "name": "孙悟空",
        "age": 100000,
        "gender": ""
    }, {
        "name": "蔡文姬",
        "age": 16,
        "gender": ""
    }]

    这......这特么不就是个列表,里面放着三个字典吗?你说的对,如果你理解成了列表和字典,那么证明了你只会Python,在其他语言中它又是别的类型了,我们把这种类型的玩意儿,叫做:Json

    这么说,可能还不太明白。看下面的表

    MySQL MongoDB
    DB DB
    Table Colletions
    字段 Field
    row Documents

    MongoDB安装

    你必须得先安装上数据库才能继续装X

    关于MongoDB的安装,真的没有难度,真的真的没有难度,来跟着DragonFire一步一步操作,带你Legendary

    首先分享给你一个MongoDB 3.4的msi安装包 点击这里可以下载哦(如果不能下载证明我还没搞定分享msi,自己下载一个吧)

    选择默认安装/选择安装

    选择 安装

    安装完成之后,开始进入配置环节,首先我们要进入目录:

    "C:Program FilesMongoDBServer3.4in"

    带着你配置环境变量,让X装的更加自然更加美:

    之后的操作,windows 7 与 windows 10 不太一样,大同小异啦

    windows 10 一路到底的"确定"

    windows 7 在这里需要注意的是,Path路径移动到最后,输入:"  ;C:Program FilesMongoDBServer3.4in  " 一定要带上 "  ;  " 哦

    因为没有找到windows 7 操作系统的计算机,所以这里只能给windows 7 的同学说声抱歉了

    OK!到了这里我们基本已经完成了部分操作了

    我们来试一下成果吧

    打开cmd窗口进行一次ZB的操作吧  

    好了目录已经有了,再次ZB试一下

    好了开启成功了

    那么服务开启了,客户端怎么去连接呢,这时我们需要另一个cmd窗口开启mongo的客户端

    到此,我们成功的完成了,服务端的部署开启,还有客户端的链接,如果你还想继续往下学习的话,我给你一句金玉良言

    千万别把这两个cmd窗口关了,不然你还得重新打开一次,哈哈哈哈哈哈哈哈!!!!

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9135630.html

    二、增删改查操作

    本章我们来学习一下关于 MongoDB的增删改查

    MongoDB根本不存在SQL语句,操作它,需要使用ORM语法

    创建数据库   

    这里和一般的关系型数据库一样,都要先建立一个自己的数据库空间

    嗯嗯嗯嗯,我感受到了你内心的惊呼,瞅瞅你们这些没见过世面的样子

    是的,MongoDB设计的比较随意,没有就认为你是在创建,use LuffyCity_Com是不存在的,所以MongoDB就认为你是要创建并使用

    这个概念一定要记清楚哦,MongoDB中如果你使用了不存在的对象,那么就等于你在创建这个对象哦

    使用了不存在的对象,就代表创建对象,我们使用这一谬论创建一张表(Collection)试试

    看来真的不是谬论,真的成功的创建了一个Oldboy的Collection

    那么接下来就是在表(Collection)中添加一条数据了,怎么添加呢?

    插入数据

    insert(不推荐)

    插入一条或者多条数据,需要带有允许插入多条的参数,这个方法目前官方已经不推荐喽

    db.Oldboy.insert({"name":"DragonFire","age":20})

    效果如下:

    > db.Oldboy.insert({"name":"DragonFire","age":20})
    WriteResult({ "nInserted" : 1 })

    insertOne

    插入一条数据,官方推荐

    db.Oldboy.insertOne({"name":"WuSir","age":20})

    效果如下:

    > db.Oldboy.insertOne({"name":"WuSir","age":20})
    {
            "acknowledged" : true,
            "insertedId" : ObjectId("5b98d462430c27444ccdd644")
    }

    我们可以看出来两种方法的返回值截然不同对吧

    insertMany

     插入多条数据,无需参数控制,官方推荐

    db.Oldboy.insertMany([{"name":"WuSir2","age":20},{"name":"WuSir3","age":20}])
    > db.Oldboy.insertMany([{"name":"WuSir2","age":20},{"name":"WuSir3","age":20}])
    {
            "acknowledged" : true,
            "insertedIds" : [
                    ObjectId("5b98d51b430c27444ccdd645"),
                    ObjectId("5b98d51b430c27444ccdd646")
            ]
    }

    这就是我们向LuffyCity_Com.Oldboy中插入了2条数据

    这里留下一个数据类型的悬念

    插入完成就要查询

    查询数据

    主要是 (find findOne) , 这里没有findMany

    find

    这里不是select,如果你的第一反应是select 证明你关系型数据库没白学

    find() 无条件查找:将该表(Collection)中所有的数据一次性返回

    > db.Oldboy.find()
    { "_id" : ObjectId("5b98d45a430c27444ccdd643"), "name" : "DragonFire", "age" : 20 }
    { "_id" : ObjectId("5b98d462430c27444ccdd644"), "name" : "WuSir", "age" : 20 }
    { "_id" : ObjectId("5b98d51b430c27444ccdd645"), "name" : "WuSir2", "age" : 20 }
    { "_id" : ObjectId("5b98d51b430c27444ccdd646"), "name" : "WuSir3", "age" : 20 }
    >
    复制代码

     条件查找:age等于20的数据,这里会返回多条结果

    > db.Oldboy.find({"age":20})
    { "_id" : ObjectId("5b98d45a430c27444ccdd643"), "name" : "DragonFire", "age" : 20 }
    { "_id" : ObjectId("5b98d462430c27444ccdd644"), "name" : "WuSir", "age" : 20 }
    { "_id" : ObjectId("5b98d51b430c27444ccdd645"), "name" : "WuSir2", "age" : 20 }
    { "_id" : ObjectId("5b98d51b430c27444ccdd646"), "name" : "WuSir3", "age" : 20 }

    说到这里,有的同学不禁要问一下:"_id":ObjectId("乱七八糟一道对看着毫无关系的一对字符串") 是什么,我们插入的时候并没有一个字段(Field)并没有_id这个,

    对了这就是MongoDB自动给我们添加到系统唯一标识"_id" 是一个ObjectId 类型,我们会在数据类型中第一个说到他(MongoDB 之 数据类型 最无聊! But 最有用! MongoDB - 3)

    findOne

    findOne()无条件查找一条数据,默认当前Collection中的第一条数据

    > db.Oldboy.findOne()
    {
            "_id" : ObjectId("5b98d45a430c27444ccdd643"),
            "name" : "DragonFire",
            "age" : 20
    }

    条件查找一条age等于19的数据,如有多条数据则返回更靠前的数据

     

    > db.Oldboy.findOne({"age":20})
    {
            "_id" : ObjectId("5b98d45a430c27444ccdd643"),
            "name" : "DragonFire",
            "age" : 20
    }

    查询数据的时候,发现了有些数据出现错误了,要修改怎么办呢?

    修改数据

    主要用到,(update updateOne updateMany) 之 跟insert一样,不推荐update的写法

    update(不推荐)

    根据条件修改该条数据的内容

    > db.Oldboy.update({"name":"DragonFire"},{$set:{"age":21}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

    把name等于DragonFire中的age改为21,这里要注意的是({"条件"},{"关键字":{"修改内容"}}),其中如果条件为空,那么将会修改Collection中所有的数据

    关于$set关键字的解释就是,本节最后再说,留个悬念

    updateOne(推荐)

    根据条件修改一条数据的内容,如出现多条,只修改最高前的数据

    举例:把age等于20的所有数据中第一条数据的name改为hello kitty

    > db.Oldboy.updateOne({"age":20},{$set:{"name":"hello kitty"}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

    updateMany(推荐)

    根据条件修改所有数据的内容,多条修改

    举例:把age等于20的所有数据中的name改为Elizabeth

    > db.Oldboy.updateMany({"age":20},{$set:{"name":"Elizabeth"}})
    { "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }

    上述中有一个$set的悬念,这个悬念呀,可能要留到再往后一些了

    但是$set:{"name":"Elizabeth"}我还是要解释一下: $set 是update时的关键字,表示我要设置name属性的值为"Elizabeth"

    那么我们之前说过MongoDB的灵活性,没有就代表我要创建,所以说如果该条Documents没有name属性,他就会自动创建一个name属性并且赋值为"Elizabeth"

    更改了半天,我觉得,这些数据我都不想要了,该怎么办呢?

    删除数据

    remove

    remove({}):无条件删除数据,这里要注意了,这是删除所有数据,清空Collection

    当然了,我现在还不会操作!

    remove还支持条件删除

    举例:删除name等于"DragonFire"的所有Document

    > db.Oldboy.remove({"name":"DragonFire"})
    WriteResult({ "nRemoved" : 1 })
    

      

    那么到这里呢,增删改查就已经完事儿了

    之后我们来说一下MongoDB的数据类型,跟你们透漏一下,MongoDB的数据类型,老(te)有(bie)意(wu)思(liao)了

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9135638.html

    三、数据类型

    丰富多彩的数据类型世界

    首先我们要先了解一下MongoDB中有什么样的数据类型:

    Object  ID :Documents 自生成的 _id

    String: 字符串,必须是utf-8

    Boolean:布尔值,true 或者false (这里有坑哦~在我们大Python中 True False 首字母大写)

    Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)

    Double:浮点数 (没有float类型,所有小数都是Double)

    Arrays:数组或者列表,多个值存储到一个键 (list哦,大Python中的List哦)

    Object:如果你学过Python的话,那么这个概念特别好理解,就是Python中的字典,这个数据类型就是字典

    Null:空数据类型 , 一个特殊的概念,None Null

    Timestamp:时间戳

    Date:存储当前日期或时间unix时间格式 (我们一般不用这个Date类型,时间戳可以秒杀一切时间类型)

    看着挺多的,但是真要是用的话,没那么复杂,很简单的哦

    剖析MongoDB的数据类型

    那么我们根据以上所说的数据类型(捡重点说,别整没用的)展开说明:

    1. Object ID

    > db.Oldboy.find()
    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Elizabeth", "age" : 20 }
    "_id" : ObjectId("5b151f8536409809ab2e6b26")
    
    "5b151f85" 代指的是时间戳,这条数据的产生时间
    "364098" 代指某台机器的机器码,存储这条数据时的机器编号
    "09ab" 代指进程ID,多进程存储数据的时候,非常有用的
    "2e6b26" 代指计数器,这里要注意的是,计数器的数字可能会出现重复,不是唯一的
    以上四种标识符拼凑成世界上唯一的ObjectID
    只要是支持MongoDB的语言,都会有一个或多个方法,对ObjectID进行转换
    可以得到以上四种信息
    
    注意:这个类型是不可以被JSON序列化的

    这是MongoDB生成的类似关系型DB表主键的唯一key,具体由24个字节组成:

    0-8字节是时间戳,

    9-14字节的机器标识符,表示MongoDB实例所在机器的不同;

    15-18字节的进程id,表示相同机器的不同MongoDB进程。

    19-24字节是计数器

    2. String

    > db.Oldboy.find()
    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Elizabeth", "age" : 20 }

    UTF-8字符串,记住是UTF-8字符串

    3. Boolean

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Elizabeth", "display" : true }

    true or false 这里首字母是小写的

    4. Integer
    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Elizabeth", "age" : 20 }

    整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)

    5. Double

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Apple", "Price" : 5.8 }

    浮点数 (MongoDB中没有float类型,所有小数都是Double)

    6. Arrays

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Apple", "place" : ["China","America","New Zealand"] }

    数组或者列表,多个值存储到一个键 (list哦,大Python中的List哦

    7. Object

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "LuffyCity", "course" : {"name" : "Python","price" : 19800 } }

    如果你学过Python的话,那么这个概念特别好理解,就是Python中的字典,这个数据类型就是字典

    8. Null

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "atmosphere", "price" : null }

    空数据类型 , 一个特殊的概念,None Null

    9. Timestamp :时间戳

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Shanghai", "date" : 1528183743111 }

    10. Date

    { "_id" : ObjectId("5b151f8536409809ab2e6b26"), "name" : "Beijing", "date" : ISODate("2018-06-05T15:28:33.705+08:00") }

    存储当前日期或时间格式 (我们一般很少使用这个Date类型,因为时间戳可以秒杀一切时间类型)

    数据类型就介绍到这里了,接下来我们就要学习一下在数据进行增删改查时,数据类型的特殊用法

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9135854.html

    四、$关键字以及$修改器

    上一篇文章中提到过 $set 这个系统关键字,用来修改值的,对吧!

    但是MongoDB中类似这样的关键字有很多, $lt $gt $lte $gte 等等,这么多我们也不方便记,这里我们说说几个比较常见的

    准备基础数据

    复制代码
    # 清空所有数据
    > db.Oldboy.remove({})
    WriteResult({ "nRemoved" : 3 })
    
    # 插入3条数据
    > db.Oldboy.insertMany([{"name":"Linux","score":59},{"name":"Python","score":100},{"name":"Go","score":80}])
    {
            "acknowledged" : true,
            "insertedIds" : [
                    ObjectId("5b98f5b3430c27444ccdd64a"),
                    ObjectId("5b98f5b3430c27444ccdd64b"),
                    ObjectId("5b98f5b3430c27444ccdd64c")
            ]
    }
    
    # 查询所有数据
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64a"), "name" : "Linux", "score" : 59 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64b"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64c"), "name" : "Go", "score" : 80 }
    复制代码

    常见的$关键字

    :(等于)

    在MongoDB中什么字段等于什么值其实就是 " : " 来搞定 比如 "name" : "Linux"

    > db.Oldboy.find({"name":"Linux"})
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64a"), "name" : "Linux", "score" : 59 }

    $gt(大于)

    在MongoDB中的 大于 > 号 我们用 : $gt  比如 :  "score" : { $gt : 80 } 就是 得到 "score" 大于 80 的数据

    > db.Oldboy.find({"score":{$gt:80}})
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64b"), "name" : "Python", "score" : 100 }

    $lt(小于)

    小于 : 在MongoDB中的 小于 < 号 我们用 : $lt  比如 :  "score" : { $lt : 80 } 就是 得到 "score" 小于 80 的数据

    > db.Oldboy.find({"score":{$lt:80}})
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64a"), "name" : "Linux", "score" : 59 }

    $gte(大于等于)

    大于等于 : 在MongoDB中的 大于等于 >= 号 我们用 : $gte  比如 :  "score" : { $gte : 80 } 就是 得到 "score" 大于等于 80 的数据

    > db.Oldboy.find({"score":{$gte:80}})
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64b"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64c"), "name" : "Go", "score" : 80 }

    $lte(小于等于)

    小于等于 : 在MongoDB中的 小于等于 <= 号 我们用 : $lte  比如 :  "score" : { $lte : 80 } 就是 得到 "score" 小于等于 80 的数据

    > db.Oldboy.find({"score":{$lte:80}})
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64a"), "name" : "Linux", "score" : 59 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64c"), "name" : "Go", "score" : 80 }

    这就是MongoDB中的运算符,是不是很类似我们使用的ORM中的运算符啊,没错,最开始的时候我们就已经说了,MongoDB的操作就是很类似ORM的

    update修改器

    常用的update修改器: $inc $set $unset $push $pull

    在此前的update中,我们用过$set,对数据进行过更新,其实在update中还存在很多的$关键字,我们把update中的这些关键字叫做 修改器

    修改器很多,这里挑一些重要的来说一说:

    1. $inc

    Python中的  变量 += 1 , 将查询到的结果 加上某一个值 然后保存

    还是上面的Collection数据,我们来试一下$inc , 让不及格的 "Linux" 变成 60 分

    > db.Oldboy.updateOne({"score":59},{$inc:{"score":1}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

    成功了 , {$inc:{"score":1}}的意思是,"score"的原有数值上面 +1

    查看所有数据

    > db.Oldboy.find()
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64a"), "name" : "Linux", "score" : 60 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64b"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64c"), "name" : "Go", "score" : 80 }

    我们再来实验一次,把60改为20,这怎么操作呢,其实可以理解为在 60 上加一个 -40

    > db.Oldboy.updateOne({"score":60},{$inc:{"score":-40}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

    又成功了 , {$inc:{"score":-20}}也来越喜欢英俊潇洒又不会翻车的自己了

    $inc 的用法是不是很简单啊,就是原有基础上在增加多少对吧

    查看所有数据

    > db.Oldboy.find()
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64a"), "name" : "Linux", "score" : 20 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64b"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98f5b3430c27444ccdd64c"), "name" : "Go", "score" : 80 }

    2. $set

    此前我们已经提到过 $set 的用法和特性(没有就自动添加一条)了

    再做一个例子:把 "score" 为 100 分 的 "price" 赋值为 99.8

    复制代码
    > db.Oldboy.updateOne({"score":100},{$set:{"price":99.8}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : "20" }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100, "price" : 99.8 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    发现Python多了一个属性price

    再把 "score" 为 20 分的 "score" 赋值为 59 分

    复制代码
    > db.Oldboy.updateOne({"score":20},{$set:{"score":59}})
    { "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100, "price" : 99.8 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    完美~

    3. $unset

    用来删除Key(field)的

    做一个小例子 : 刚才我们有一个新的"price" 这个field ,现在我们来删除它

    复制代码
    > db.Oldboy.updateOne({"score":100},{$unset:{"price":1}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    成功了! {$unset:{"price" : 1}} 就是删除 "english_name" 这个 field 相当于 关系型数据库中删除了 字段

    4. $push

    它是用来对Array (list)数据类型进行 增加 新元素的,相当于我们大Python中 list.append() 方法

    做一个小例子 :首先我们要先对原有数据增加一个Array类型的field:

    复制代码
    > db.Oldboy.update({},{$set:{"test_list":[1,2,3,4,5]}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    使用update $set 的方法只能为Document中的第一条添加

    使用updateMany $set 的方法 可以为所有满足条件的 Document 添加 "test_list" , 注意我这里的条件为空 " {} " 就算是为空,也要写上"{}" 记住记住记住

    接下来我们就要队列表进行添加了: 将 "score" 为 59 的Document 中"test_list" 添加一个 6

    复制代码
    > db.Oldboy.updateMany({"score":59},{$push:{"test_list":6}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5, 6 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    $push 是在 Array(list) 的尾端加入一个新的元素  {$push : {"test_list" : 6}}

    5. $pull

    有了$push 对Array类型进行增加,就一定有办法对其内部进行删减,$pull 就是指定删除Array中的某一个元素

    做一个例子: 把我们刚才$push进去的 6 删除掉

    复制代码
    > db.Oldboy.updateMany({"score":59},{$pull:{"test_list":6}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    问题来了,如果 Array 数据类型中 如果有 多个 6 怎么办呢?

    重复执行3条命令,查看所有数据

    复制代码
    > db.Oldboy.updateMany({"score":59},{$push:{"test_list":6}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.updateMany({"score":59},{$push:{"test_list":6}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.updateMany({"score":59},{$push:{"test_list":6}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5, 6, 6, 6 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    再次执行命令,删除6

    复制代码
    > db.Oldboy.updateMany({"score":59},{$pull:{"test_list":6}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    全部删掉了.....

    得出了一个结论,只要满足条件,就会将Array中所有满足条件的数据全部清除掉

    6. $pop

    指定删除Array中的第一个 或 最后一个 元素

    做个小例子: 删除"score" 等于 59 分  test_list 的最后一个元素

    复制代码
    > db.Oldboy.updateMany({"score":59},{$pop:{"test_list":1}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 1, 2, 3, 4 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

     怎么删除第一个呢?

    复制代码
    > db.Oldboy.updateMany({"score":59},{$pop:{"test_list":-1}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b98faa9430c27444ccdd64d"), "name" : "Linux", "score" : 59, "test_list" : [ 2, 3, 4 ] }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64e"), "name" : "Python", "score" : 100 }
    { "_id" : ObjectId("5b98faa9430c27444ccdd64f"), "name" : "Go", "score" : 80 }
    复制代码

    {$pop:{"test_list" : -1}}  -1 代表最前面, 1 代表最后边 (这和我们大Python正好相反) 记住哦

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9141976.html

    五、"$"的奇妙用法

    在MongoDB中有一个非常神奇的符号 "$"

    "$"  在 update 中 加上关键字 就 变成了 修改器

    其实 "$" 字符 独立出现也是有意义的 , 我起名叫做代指符

    准备基础数据

     View Code

    首先看个例子:  现在把 "score": 100 的 test_list 里面的 2 改为 9

    复制代码
    > db.Oldboy.updateOne({"score":100},{$set:{"test_list.0":9}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b990189430c27444ccdd650"), "name" : "Linux", "score" : 100, "test_list" : [ 9, 3, 4 ] }
    { "_id" : ObjectId("5b990189430c27444ccdd651"), "name" : "Python", "score" : 80, "test_list" : [ 1, 2, 3, 4, 5 ] }
    { "_id" : ObjectId("5b990189430c27444ccdd652"), "name" : "Go", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5 ] }
    复制代码

    {$set :{"test_list.0" : 9}} 这样就是对应 Array 中的下标进行修改了 "test_list.下标"

    问题来了 如果 是 一个很长很长很长的 Array 你要查找其中一个值,把这个值修改一下怎么整呢?

    把9还原成2

    复制代码
    > db.Oldboy.updateMany({"score":100,"test_list":9},{$set:{"test_list.$":2}})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.Oldboy.find()
    { "_id" : ObjectId("5b990189430c27444ccdd650"), "name" : "Linux", "score" : 100, "test_list" : [ 2, 3, 4 ] }
    { "_id" : ObjectId("5b990189430c27444ccdd651"), "name" : "Python", "score" : 80, "test_list" : [ 1, 2, 3, 4, 5 ] }
    { "_id" : ObjectId("5b990189430c27444ccdd652"), "name" : "Go", "score" : 59, "test_list" : [ 1, 2, 3, 4, 5 ] }
    复制代码

    神奇不神奇?

    $ 字符 在语句中代表了什么呢? 下标,位置

    解释一下: 首先我们查询一下db.Oldboy.findOne({"score":100,"test_list":3}) 返回 给我们满足条件的数据对吧

    复制代码
    > db.Oldboy.findOne({"score":100,"test_list":3})
    {
            "_id" : ObjectId("5b990189430c27444ccdd650"),
            "name" : "Linux",
            "score" : 100,
            "test_list" : [
                    2,
                    3,
                    4
            ]
    }
    复制代码

    那么 如果 我们 使用 update的话, 满足条件的数据下标位置就会传递到 $ 字符中,在我们更新操作的时候就相当于 对这个位置 的元素进行操作

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9146896.html

    六、Array Object 的特殊操作

    相比关系型数据库, Array [1,2,3,4,5] 和 Object { 'name':'DragonFire' } 是MongoDB 比较特殊的类型了

    特殊在哪里呢?在他们的操作上又有什么需要注意的呢?

    那我们先建立一条数据,包含 Array 和 Object 类型

     View Code

    数据看着可能不太直观,大概是这个样子

    复制代码
    {
        "_id" : ObjectId("5b17d01a49bf137b585df891"),
        "name" : "路飞学城-骑士计划",
        "price" : [
            19800,
            19500,
            19000,
        ],
        "other" : {
            "start" : "2018年8月1日",
            "start_time" : "08:30",
            "count" : 150
        }
    }
    复制代码

    好的,这条数据已经完成了

    针对这条数据我们进行一系列的操作,并讲解使用方式

    Array 小秀一波

    把price 中 19000 改为 19300

    > db.Oldboy.update({"name":"路飞学城-骑士计划"},{$set:{"price.2":19300}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.Oldboy.find()
    { "_id" : ObjectId("5b990568430c27444ccdd653"), "name" : "路飞学城-骑士计划", "price" : [ 19800, 19500, 19300, 18800 ], "other" : { "start" : "2018年8月1日", "start_time" : "08:30", "count" : 150 } }

    db.Oldboy.update({"name":"路飞学城-骑士计划"},{$set:{"price.2":19300}})

    我们用了引用下标的方法更改了数值 , "price.2"代指的是 Array 中第3个元素

    混合用法

    如果 price.1 中小于19800 则加 200

    > db.Oldboy.update({"name":"路飞学城-骑士计划","price.1":{$lt:19800}},{$inc:{"price.1":200}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.Oldboy.find()                                                                   ":200}})
    { "_id" : ObjectId("5b990568430c27444ccdd653"), "name" : "路飞学城-骑士计划", "price" : [ 19800, 19700, 19300, 18800 ], "other" : { "start" : "2018年8月1日", "start_time" : "08:30", "count" : 150 } }

    发现第二个价格,加了200块!

    复习一下:"price.1":{$lt:19800} 是查找 price.1 小于 19800

    复习两下:{$inc:{"price.1":200}} 是什么啊? price.1 拿出来 加上 200 之后 再存进去

    那么顺理成章的混合到一起了

    上节课我们也学习了 $ 的用法,现在我们混搭 $ 再做一个练习

    我们把 price 小于 19500  的 自动补上 200

    > db.Oldboy.update({"name":"路飞学城-骑士计划","price":{$lt:19500}},{$inc:{"price.$":200}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.Oldboy.find()
    { "_id" : ObjectId("5b990568430c27444ccdd653"), "name" : "路飞学城-骑士计划", "price" : [ 19800, 19700, 19500, 18800 ], "other" : { "start" : "2018年8月1日", "start_time" : "08:30", "count" : 150 } }

    发现第3个更改了!18800并没有更改

    细心的同学已经发现了,只改了第一个匹配的!是的 $ 这个只储存一个下标。

    批量更改的话,嘻嘻嘻嘻截至2017年1月1日,MongoDB没有这个功能

    你只要把这个Array 拿出来,在程序里面改完,原方不动的放回去不就搞定了吗

    Object 字典

    Object 字典总玩儿过吧,但是这里更像是 JavaScript 中的 Object 对象

    1. 把other中 count 改为 199

    > db.Oldboy.update({"name":"路飞学城-骑士计划"},{$set:{"other.count":199}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.Oldboy.find()
    { "_id" : ObjectId("5b990568430c27444ccdd653"), "name" : "路飞学城-骑士计划", "price" : [ 19800, 19700, 19500, 18800 ], "other" : { "start" : "2018年8月1日", "start_time" : "08:30", "count" : 199 } }

    对了就是在这个对象 打点儿 key 就可以更改数值了 , 要注意的是, 咱们用的 $set 进行修改的,那么就意味着,如果没有"other.count"这个field的话,他会自动创建

    这个用法就到这里了,下面我们玩儿个更深的

    2. 混合用法

    如果 count 小于 200 那么 加 10

    > db.Oldboy.update({"name":"路飞学城-骑士计划","other.count":{$lt:200}},{$inc:{"other.count":10}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.Oldboy.find()
    { "_id" : ObjectId("5b990568430c27444ccdd653"), "name" : "路飞学城-骑士计划", "price" : [ 19800, 19700, 19500, 18800 ], "other" : { "start" : "2018年8月1日", "start_time" : "08:30", "count" : 209 } }

    这么玩儿完了之后,条件位置的打点儿调用,也尝试过了

    Object的用法就这么多了

    Array + Object 的用法

    Array + Object 的用法 告诉你们,这个老High了

    首先,我们要先建立一条 Document 嘻嘻嘻嘻嘻

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9147430.html

    七、选取跳过排序

    本文参考链接:

    https://www.cnblogs.com/DragonFire/p/9154832.html

    今日内容总结

     View Code

    今日作业

     View Code
  • 相关阅读:
    P1642 规划 [01分数规划]
    01分数规划学习笔记
    P1527 [国家集训队]矩阵乘法 [整体二分]
    P3292 [SCOI2016]幸运数字 [线性基+倍增]
    java中遍历集合的三种方式
    20190706中兴提前批专业面面经
    《java入门如此简单》——语句,函数和数组
    java中数组常见的操作
    2019 波克城市ava面试笔试题 (含面试题解析)
    2019 华云数据java面试笔试题 (含面试题解析)
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/9637486.html
Copyright © 2020-2023  润新知