zoukankan      html  css  js  c++  java
  • MongoDB

    一、初识MongoDB

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

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

      简单说,MongoDB和我们使用的关系型数据库最大的区别就是约束性,可以说文件型数据库几乎不存在约束性,理论上没有主外键约束,没有存储的数据类型约束等等。关系型数据库中有一个 "表" 的概念, "字段" 的概念, "数据条目" 的概念,MongoDB中也同样有以上的概念,,但是名称发生了一些变化,严格意义上来说,两者的概念即为相似,但又有些出入,不过无所谓,我们就当是以上概念就好啦。

      用如下示例进一步说明:

      这是我们用关系型数据库做的一张很简单的user表:

      id   name    age     gender
      1    刘涛     36      female
      2    孙红雷   40       male
      3    马伊利   35      female

      在MongoDB的数据结构如下:

      user = [
        {
          "id": 1,
          "name": "刘涛",
          "age": 36,
          "gender": female
        },
        {
          "id": 2,
          "name": "孙红雷",
          "age": 40,
          "gender": male
        },
        {
          "id": 3,
          "name": "马伊利",
          "age": 35,
          "gender": female
        }
      ]

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

      那么你应该恍然大悟了吧,MongoDB的每个表(Collection)中存储的每条数据(Documents)都是一个一个的Json,Json中的每一个字段(Key)我们称之为Field,就此我们引出了三个关键字:Collection也就是关系型数据库中"表"的概念,Documents就是"数据条目",Field就是"字段"。

      接下来在你的电脑上安装MongoDB,本文以3.4版本为例,安装过程一路下一步即可,完成后找到安装目录下的bin目录,将其加入环境变量。

      注意:安装完成后打开终端,输入mongod,会显示如下错误信息:

      我们可以手动在上述提示目录,即c盘创建datadb目录,若不想放在c盘,也可以在其他磁盘,如d盘创建,如下:

      此时就可以成功开启mongodb服务了,且要指定mongodb的数据存放目录,如下:

      开启服务端后再打开一个终端开启mongo的客户端,如下:

      接下来就可以进行mongodb的操作了,如下图:

      注意:由上图我们发现,mongodb中使用了不存在的对象,就代表创建对象,接下来我们使用这以结论创建一张表(collection),如下图:

    二、MongoDB的数据类型 

      ObjectID :Documents 自生成的 _id;
      String: 字符串,必须是utf-8;
      Boolean:布尔值,true 或者false (注意,这里首字母要小写);
      Integer:整数 (Int32、Int64,就知道有个Int就行了,一般我们用Int32);
      Double:浮点数 (没有float类型,所有小数都是Double);
      Arrays:数组或者列表,多个值存储到一个键;
      Object:相当于Python中的字典;
      Null:空数据类型;
      Timestamp:时间戳;
      Date:存储当前日期或时间unix时间格式 (我们一般不用这个Date类型,时间戳可以秒杀一切时间类型);

      这里我们重点说一下ObjectID类型,它是MongoDB生成的类似关系型DB表主键的唯一key,具体由24个字节组成:

      1-8字节是时间戳;

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

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

      19-24字节是计数器;

      "_id" : ObjectId("5c3ee043949505956bbf9b33")
      
    #"5c3ee043" 代指的是时间戳,这条数据的产生时间;   #"949505" 代指某台机器的机器码,存储这条数据时的机器编号;   #"956b" 代指进程ID,多进程存储数据的时候,非常有用的;   #"bf9b33" 代指计数器,这里要注意的是,计数器的数字可能会出现重复,不是唯一的;   # 以上四种标识符拼凑成世界上唯一的ObjectID   # 只要是支持MongoDB的语言,都会有一个或多个方法,对ObjectID进行转换   # 注意:这个类型是不可以被JSON序列化的

    三、MongoDB的增删改查

    1、插入数据(insertinsert_oneinsert_many

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

      insertOne({}):插入一条数据,官方推荐

      insertMany([{}]):插入多条数据,无需参数控制,官方推荐

    2、查询数据(findfindOne

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

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

      find({条件},{排除字段}),示例如下:

     

    3、修改数据(updateupdateOneupdateMany

      语法:update/updateOne/updateMany({"条件"},{"关键字":{"修改内容"}})

      解释:根据条件修改内容,其中如果条件为空,那么将会修改Collection中所有的数据

      示例:

      update({"name":"tom"},{$set:{"age":43}}):表示将表中name等于tom的记录(documents)的age字段(field)改为21,与insert一样,官方已经不推荐

      updateOne({"age":43},{$set:{"age":25}}):将表中age等于43的记录(documents)的age字段(field)改为25,如出现多条符合条件的记录,只修改最靠前的数据,3.2版本之后有的,官方推荐

      updateMany({"age":25},{$set:{"age":22}}):将表中age等于25的记录(documents)的age字段(field)改为22,如出现多条符合条件的记录,修改所有符合条件的数据,3.2版本之后有的,官方推荐

    4、删除数据(removedeleteOnedeleteMany

      remove:删除满足条件的数据或者删除全部数据,官方已经不推荐了

      deleteOne:删除符合条件的一条数据,若有多条符合条件,默认删除符合条件的第一条,3.2版本之后有的,官方推荐写法

      deleteMany:删除符合条件的所有数据,若有多条符合条件,则删除符合条件的所有数据,3.2版本之后有的,官方推荐写法 

    5、查询中的数学比较符关键字( $lt、$gt、$lte、$gte$eq)

      $ltMongoDB中的"<",用"$lt",比如: "age":{$lt:22} 就是得到"age"小于22的数据

      $gt:MongoDB中的">",用"$gt",比如: "age":{$gt:22} 就是得到"age"大于22的数据

      $lteMongoDB中的"<=",用"$lte",比如: "age":{$lte:22} 就是得到"age"小于等于22的数据

      $gteMongoDB中的">=",用"$gte",比如: "age":{$gte:22} 就是得到"age"大于等于22的数据

      $eq:我们在之前的查询中遇到什么字段等于什么值时,使用冒号":"来表示,比如"name":"tom",除此之外,MongoDB中的"=",还可以用关键字"$eq"表示,比如:"age":{$eq:22} 就是得到"age"等于22的数据,但通常用冒号":"表示即可,不能用冒号的可用关键字"$eq"

    6、查询条件并列关系、或( $or )关系、子集( $in )关系、完全符合( $all )关系
      1)find({"name":"张三","age":15})

      2)find({$or:[{"name":"tom"},{"age":15}]})

      3)find({"age":{$in:[10,20,30,40]}}) 或者 find({"score":{$in:[55,77,80,91]}})

      4)find({"score":{$all:[58,88,77,95]}})

    7、MongoDB中的那些update修改器($inc、$set、$unset、$push、$pull$pushAll$pop) 

      在之前的update中,我们用过$set对数据进行修改,其实在update中还存在很多的$关键字,我们把update中的这些关键字叫做修改器,修改器很多,下面结合示例介绍几个:

      1)$inc:将查询到的结果,加上某一个值,然后保存

      2$set:暴力修改,我们在mongodb的基本操作中已经使用过该修改器

      3$unset:用来暴力删除字段(field

      4$push:用来对Array数据类型进行 增加 新元素的,相当于Pythonlist.append() 方法

      5$pull:用来对Array数据类型进行 删除 元素的,相当于Pythonlist.remove() 方法

      6$pushAll:用来对Array数据类型进行 迭代追加 ,相当于Pythonlist.extend() 方法

      7$pop:指定删除Array中的第一个 或 最后一个 元素

    8、"$"符的奇妙用法
      在
    MongoDB中有一个非常神奇的符号 "$","$"在update中加上关键字就变成了修改器,其实"$"字符独立出现也是有意义的,它代表符合条件的元素下标

      有如下collections:

      现需要把tom的score_list列表中的59改为60,操作如下:

      那么问题来了,若score_list中元素很多,且不知道要修改的元素索引,只知道修改前的值和修改后的值,此时改如何做呢?没错,就是使用"$",如下:

      注意:$中只能存储一个值,且是符合条件的第一个值。

    9、MongoDB的Array、Object的特殊操作

      相比关系型数据库,Array和Object是MongoDB比较特殊的类型了,特殊在哪里呢?在他们的操作上又有什么需要注意的呢?

      我们先建立一条数据(documents),包含 Array 和 Object 类型:

      {
        "_id" : ObjectId("5c406c65456ef1f8f2b06401"),
        "name" : "tom",
        "score" : [
            98,
            95,
            90,
            88
        ],
        "girlfriend" : {
            "name" : "alex",
            "gender" : "female",
            "age" : 30
        }
      }

      

      1)示例一:将score列表中的90改为80

     

      2)示例二:将tom的小于85的分数加上2分

      3)示例三:$只能存储一个值

      4)示例四:将girlfriend的age改为22

      5)示例五:若tom的girlfriend的age小于25时,给其值加2

      6)示例六:Array中嵌套Object的操作

        我们再建立如下数据演示:

      {
          "_id" : ObjectId("5c407d5e456ef1f8f2b06402"),
          "name" : "tom",
          "chengji" : [
              {
                  "title" : "python",
                  "desc" : "very good",
                  "score" : 90
              },
              {
                  "title" : "linux",
                  "desc" : "bad",
                  "score" : 60
              },
           {
                  "title" : "java",
                  "desc" : "good",
                  "score" : 82
           }
          ]
      }
      db.userinfo.update({"chengji.score":{$lt:70}},{$inc:{"chengji.$.score":2}})

      {"chengji.score":{$lt:70}},虽然chengjiArray,表示从内部的Object中找到score小于70的结果

      {$inc:{"chengji.$.score":2}}chengji中第$(小于70的第一个)Objectscore2

    10、Limit、Skip、Sort
      1)Limit 选取 : 从 Documents 中取出多少个

      2)Skip 跳过 : 跳过多少个Documents

      3)Sort 排序 : 将结果按照关键字排序(1 为升序 , -1 为降序) 

      4)Limit + Skip + Sort 混合使用

      注意:Sort + Skip + Limit 是有执行优先级的,他们的界别分别是,优先 Sort 其次 Skip 最后 Limt。

    四、pymongo

      类似pymysql,pymongo是python中操作mongodb数据库的模块。

    1、安装

    pip3 install pymongo

    2、使用pymongo

      1)增加

      import pymongo
    
      mongoclient = pymongo.MongoClient(host="127.0.0.1", port=27017)
      MongoDB = mongoclient["db1"]   # db1是mongodb中的一个数据库
    
      res = MongoDB.userinfo.insert_one({"name":"wusir", "age":32})
    
      print(res)  
      # <pymongo.results.InsertOneResult object at 0x0000019DEA5B6FC8>
      print(type(res))  # <class 'pymongo.results.InsertOneResult'>
      print(res.inserted_id) # 5c3eee24cf0e440838f79d3a
      print(type(res.inserted_id)) # <class 'bson.objectid.ObjectId'>
    
      res = MongoDB.userinfo.insert_many([
          {"name":"张三", "age":30},
          {"name":"李四", "age":18}
      ])
    
      print(res)  
      # <pymongo.results.InsertManyResult object at 0x000001DE80351088>
      print(type(res))  # <class 'pymongo.results.InsertManyResult'>
      print(res.inserted_ids) # [ObjectId('5c3eef71cf0e440ba4f5c40d'), ObjectId('5c3eef71cf0e440ba4f5c40e')]

      总结:

        - insert_one()插入数据一条数据(documents),返回值的inserted_id表示插入数据的"_id"值,ObjectID类型;

        - insert_many([])插入多条数据documents),返回值的inserted_ids表示插入数据的"_id"值组成的列表,列表中的元素也是ObjectID类型;

      2)查询

      import pymongo
    
      mongoclient = pymongo.MongoClient(host="127.0.0.1", port=27017)
      MongoDB = mongoclient["db1"]   # db1是mongodb中的一个数据库
      
      res = MongoDB.userinfo.find_one()  # 查询一条数据,返回字典
      print(res)
      # {'_id': ObjectId('5c3ee043949505956bbf9b33'), 'name': 'tom', 'age': 12.0}
    
      res = MongoDB.userinfo.find()  # 查询所有数据,返回cursor对象,可迭代
      print(res)
      # <pymongo.cursor.Cursor object at 0x0000016CF07D7358>
      print(list(res))
      # [{'_id': ObjectId('5c3ee043949505956bbf9b33'), 'name': 'tom', 'age': 12.0}, 
      # {'_id': ObjectId('5c3eed9dcf0e440980eb4e45'), 'name': 'alex', 'age': 38}, 
      # {'_id': ObjectId('5c3eee24cf0e440838f79d3a'), 'name': 'wusir', 'age': 32}, 
      # {'_id': ObjectId('5c3eef71cf0e440ba4f5c40d'), 'name': '张三', 'age': 30}, 
      # {'_id': ObjectId('5c3eef71cf0e440ba4f5c40e'), 'name': '李四', 'age': 18}]

      注意:同mongodb一样,pymongo也可以find({条件},{排除字段})或者find_one({条件},{排除字段})

      3)修改

      import pymongo
    
      mongoclient = pymongo.MongoClient(host="127.0.0.1", port=27017)
      MongoDB = mongoclient["db1"]   # db1是mongodb中的一个数据库
    
      res = MongoDB.userinfo.update_one({"name":"tom"},{"$set":{"age":15}})
    
      print(res)
      # <pymongo.results.UpdateResult object at 0x000001A888325E08>
      print(dir(res))
      # [..., '__delattr__',..., 'raw_result', 'upserted_id']
    
      res = MongoDB.userinfo.update_many({"age":15},{"$set":{"age":22}})
      print(res.raw_result)  # 修改结果,包括影响行数,是否存在需要修改的数据等
      # {'n': 2, 'nModified': 2, 'ok': 1.0, 'updatedExisting': True}

      总结:除上例中的$set之外,$push、$pull等方法都可以使用。

      4)删除

      import pymongo
    
      mongoclient = pymongo.MongoClient(host="127.0.0.1", port=27017)
      MongoDB = mongoclient["db1"]   # db1是mongodb中的一个数据库
    
      res = MongoDB.userinfo.delete_one({"name":"wusir"})
      res = MongoDB.userinfo.delete_many({"age":22})

      5)sort、limit、skip

      import pymongo
    
      mongoclient = pymongo.MongoClient(host="127.0.0.1", port=27017)
      MongoDB = mongoclient["db1"]   # db1是mongodb中的一个数据库
    
      res = MongoDB.userinfo.find().skip(2).limit(2)  # 跳过两条,显示两条
      print(list(res))
    
      # pymongo.ASCENDING表示升序,pymongo.DESCENDING表示降序
      res = MongoDB.userinfo.find().sort("age", pymongo.ASCENDING)
      print(list(res))
      res = MongoDB.userinfo.find().sort("age", pymongo.DESCENDING)
      print(list(res))

      6)字符串类型与ObjectID类型的相互转换

        我们知道ObjectID不能被序列化,而mongodb中的"_id"是ObjectID类型数据,且经常需要将数据json序列化后进行传输,下面介绍字符串类型与ObjectID类型相互转换。

      import pymongo
      from bson import ObjectId
    
      mongoclient = pymongo.MongoClient(host="127.0.0.1", port=27017)
      MongoDB = mongoclient["db1"]   # db1是mongodb中的一个数据库
    
      res = MongoDB.userinfo.find_one()
      s = res.get("_id")
      print(s)  # 5c3eef71cf0e440ba4f5c40d
      print(type(s))  # <class 'bson.objectid.ObjectId'>
      print(str(s))  # 5c3eef71cf0e440ba4f5c40d
      print(type(str(s)))  # <class 'str'>
    
      s = ObjectId("5c3eef71cf0e440ba4f5c40d")      # 强转成ObjectID类型
      res = MongoDB.userinfo.find_one({"_id":s})
      print(res)
      # {'_id': ObjectId('5c3eef71cf0e440ba4f5c40d'), 'name': '张三', 'age': 30}

     

  • 相关阅读:
    atitit.nfc 身份证 银行卡 芯片卡 解决方案 attilax总结
    atitit.php 流行框架 前三甲为:Laravel、Phalcon、Symfony2 attilax 总结
    Atitit.执行cmd 命令行 php
    Atitit. 图像处理jpg图片的压缩 清理垃圾图片 java版本
    atitit。企业组织与软件工程的策略 战略 趋势 原则 attilax 大总结
    atitit. 管理哲学 大毁灭 如何防止企业的自我毁灭
    Atitit.java的浏览器插件技术 Applet japplet attilax总结
    Atitit.jquery 版本新特性attilax总结
    Atitit. 软件开发中的管理哲学一个伟大的事业必然是过程导向为主 过程导向 vs 结果导向
    (转)获取手机的IMEI号
  • 原文地址:https://www.cnblogs.com/li-li/p/10276355.html
Copyright © 2011-2022 走看看