03-數(shù)據(jù)庫MongoDB[Python]

一挪钓、MongoDB簡介

  • 概述
    MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫,由C++語言編寫。旨在為WEB應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案南蹂。

    MongoDB介于關(guān)系型數(shù)據(jù)和非關(guān)系型數(shù)據(jù)庫之間佃乘,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富囱井,最像關(guān)系數(shù)據(jù)庫的。他支持的數(shù)據(jù)結(jié)構(gòu)非常松散恕稠,類似json格式琅绅,因此可以存儲(chǔ)比較復(fù)雜的數(shù)據(jù)類型。

    MongoDB最大的特點(diǎn)是他支持的查詢語言非常強(qiáng)大鹅巍,其語法有點(diǎn)類似于面向?qū)ο蟮牟樵冋Z言千扶,幾乎可以實(shí)現(xiàn)類似關(guān)系數(shù)據(jù)庫表單查詢的絕大部分功能料祠,而且還支持對(duì)數(shù)據(jù)建立索引。

  • MySQL
    關(guān)系型數(shù)據(jù)庫澎羞。 查詢語句是使用傳統(tǒng)的sql語句髓绽,擁有較為成熟的體系,成熟度很高妆绞。 關(guān)系型數(shù)據(jù)庫遵循ACID規(guī)則 開源數(shù)據(jù)庫的份額在不斷增加顺呕,mysql的份額頁在持續(xù)增長。 缺點(diǎn):在海量數(shù)據(jù)處理的時(shí)候效率會(huì)顯著變慢括饶。

    數(shù)據(jù)庫事務(wù)必須具備ACID特性株茶,ACID是Atomic原子性,Consistency一致性图焰,Isolation隔離性启盛,Durability持久性。
    數(shù)據(jù)的持久存儲(chǔ)技羔,尤其是海量數(shù)據(jù)的持久存儲(chǔ)僵闯,還是需要一種關(guān)系數(shù)據(jù)庫。

  • MongoDB
    非關(guān)系型數(shù)據(jù)庫(nosql ),屬于文檔型數(shù)據(jù)庫藤滥。存儲(chǔ)方式:虛擬內(nèi)存+持久化鳖粟。
    查詢語句:是獨(dú)特的MongoDB的查詢方式。
    適合場(chǎng)景:事件的記錄拙绊,內(nèi)容管理或者博客平臺(tái)等等向图。
    數(shù)據(jù)處理:數(shù)據(jù)是存儲(chǔ)在硬盤上的,只不過需要經(jīng)常讀取的數(shù)據(jù)會(huì)被加載到內(nèi)存中时呀,將數(shù)據(jù)存儲(chǔ)在物理內(nèi)存中张漂,從而達(dá)到高速讀寫。
    成熟度與廣泛度:新興數(shù)據(jù)庫谨娜,成熟度較低航攒,Nosql數(shù)據(jù)庫中最為接近關(guān)系型數(shù)據(jù)庫,比較完善的DB之一趴梢,適用人群不斷在增長漠畜。
    優(yōu)勢(shì): 快速!在適量級(jí)的內(nèi)存的MongoDB的性能是非常迅速的坞靶,它將熱數(shù)據(jù)存儲(chǔ)在物理內(nèi)存中憔狞,使得熱數(shù)據(jù)的讀寫變得十分快, 高擴(kuò)展彰阴, json的存儲(chǔ)格式瘾敢!

    文檔的數(shù)據(jù)庫: 即可以存放xml、json、bson類型系那個(gè)的數(shù)據(jù)簇抵。這些數(shù)據(jù)具備自述性(self-describing)庆杜,呈現(xiàn)分層的樹狀數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)結(jié)構(gòu)由鍵值(key=>value)對(duì)組成碟摆。

  • 關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫的區(qū)別
    關(guān)系型數(shù)據(jù)庫通過外鍵關(guān)聯(lián)來建立表與表之間的關(guān)系晃财;
    非關(guān)系型數(shù)據(jù)庫通常指數(shù)據(jù)以對(duì)象的形式存儲(chǔ)在數(shù)據(jù)庫中,而對(duì)象之間的關(guān)系通過每個(gè)對(duì)象自身的屬性來決定典蜕;

    學(xué)生: 張三
    性別: 男
    科目: 語文
    成績: 80
    
    關(guān)系型數(shù)據(jù)庫:
      // 學(xué)生表
      create table student(id int primary key, name char(50), sex char(10))
      // 成績表断盛,stuid存儲(chǔ)的是學(xué)生表中對(duì)應(yīng)的主鍵,用于表的關(guān)聯(lián)
      create table score(id int primary key, name char(20),grade int,stuid int, foreign key(stuid) references student(id))
    
    非關(guān)系型數(shù)據(jù)庫:
    {
      "name":"張三",
      "sex":"男",
      "score":{
        "name":"語文",
        "grade": 80
      }
    }
    
    

    關(guān)系型數(shù)據(jù)庫SQLite愉舔、Oracle钢猛、mysql
    非關(guān)系型數(shù)據(jù)庫 MongoDb、redis

  • MySQL和MongoDB的區(qū)別
    數(shù)據(jù)庫: 容器屑宠,不管是mysql還是mongodb厢洞,一個(gè)單一的服務(wù)器都可以管理多個(gè)數(shù)據(jù)庫;
    集合:是一組mongodb的文件仇让,等價(jià)于mysql中的table典奉,集合中文檔可以有不同的字段,也可以有不同的數(shù)據(jù)類型;

MySQL和MongoDB的區(qū)別

二丧叽、MongoDB安裝和卸載

  • 卸載

    sudo apt-get autoremove mongodb
    sudo apt-get autoclean mongodb
    
    // 清除殘留數(shù)據(jù)
    dpkg -l |grep ^rc|awk '{print $2}' |tr ["\n"] [" "]|sudo xargs dpkg -P   
    
    
  • 安裝

    第1步 – 導(dǎo)入公鑰**
      Ubuntu軟件包管理器apt(高級(jí)軟件包工具)需要軟件分銷商的GPG密鑰來確保軟件包的一致性和真實(shí)性卫玖。 執(zhí)行此下面的命令將MongoDB密鑰導(dǎo)入到您的服務(wù)器:
      sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
    
    第2步 – 創(chuàng)建源列表文件MongoDB
      檢查URL http://repo.mongodb.org/apt/ubuntu/dists/。
      如果您在該網(wǎng)頁上看到一個(gè)目錄“bionic”踊淳,則將下述命令中的單詞“xenial”替換為“bionic”一詞假瞬,
    【原因:MongoDB尚未發(fā)布Bionic Beaver軟件包,但Xenial軟件包在Ubuntu 18.04 LTS上運(yùn)行良好】
      執(zhí)行以下命令在/etc/apt/sources.list.d/中創(chuàng)建一個(gè)MongoDB列表文件:
      echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
    
    第3步 – 更新存儲(chǔ)庫
      使用apt命令更新存儲(chǔ)庫:
      sudo apt-get update
      說明:執(zhí)行完會(huì)提示一些失敗迂尝,不用在意
    
    第4步 – 安裝MongoDB
      執(zhí)行以下命令來安裝MongoDB:
      sudo apt-get install -y mongodb
    
    第5步:啟動(dòng)MongoDB
      執(zhí)行以下命令啟動(dòng)MongoDB并將其添加為在啟動(dòng)時(shí)啟動(dòng)的服務(wù)
      sudo systemctl start mongodb
    
        如果執(zhí)行完這一步終端沒有任何輸出脱茉,則說明是正確的
        如果啟動(dòng)的時(shí)候提示:Failed to start mongod.service: Unit mongodb.service not found.
        解決辦法如下:
        1創(chuàng)建配置文件:
          cd /etc/systemd/system/
          sudo vi mongodb.service
        2.在里面追加文本:
          [Unit]
          Description=High-performance, schema-free document-oriented database
          After=network.target
          [Service]
          User=mongodb
          ExecStart=/usr/bin/mongod --quiet --config /etc/mongodb.conf
          [Install]
          WantedBy=multi-user.target
        3.退出
          :wq
        4.啟動(dòng)服務(wù)
          sudo systemctl start mongodb
          sudo systemctl status mongodb
        5.設(shè)置開機(jī)自啟動(dòng)
          sudo systemctl enable mongodb
    
    第6步:登錄MongoDB
        mongo
    
          如果出現(xiàn)錯(cuò)誤全局初始化失敗:BadValue無效或無用戶區(qū)域設(shè)置垄开。 請(qǐng)確保LANG和/或LC_ *環(huán)境變量設(shè)置正確琴许,請(qǐng)嘗試命令:
          export LC_ALL=C
    
    

三、MongoDB之?dāng)?shù)據(jù)庫操作

  • 創(chuàng)建數(shù)據(jù)庫

    # mongodb
    use DATABASE_NAME
    注意:如果指定的數(shù)據(jù)庫DATABASE_NAME不存在溉躲,則該命令將創(chuàng)建一個(gè)新的數(shù)據(jù)庫榜田,否則返回現(xiàn)有的數(shù)據(jù)庫
    
    # mysql中
    創(chuàng)建數(shù)據(jù)庫:create database basename;
    切換數(shù)據(jù)庫:use basename;
    
    

    admin:從權(quán)限的角度來說,是root的數(shù)據(jù)庫
    ? local:本地?cái)?shù)據(jù)
    ? config:配置锻梳,用于保存MongoDB的配置信息

  • 檢查當(dāng)前選擇的數(shù)據(jù)

    db
    
    

    默認(rèn)的數(shù)據(jù)庫test

  • 顯示數(shù)據(jù)庫列表

    show dbs 
    
    
  • 刪除數(shù)據(jù)庫

    // 默認(rèn)進(jìn)入數(shù)據(jù)庫是test
    db.dropDatabase()
    
    

    注意:默認(rèn)刪除當(dāng)前正在工作的數(shù)據(jù)庫

四箭券、MongoDB之集合操作

類似于MySQL中的表。
集合存在于數(shù)據(jù)庫中疑枯,集合沒有固定的結(jié)構(gòu)辩块,意味著可以對(duì)集合插入不同格式和不同類型的數(shù)據(jù),但是盡量插入集合的時(shí)候保證數(shù)據(jù)的關(guān)聯(lián)性。

  • 創(chuàng)建集合

    集合名的規(guī)范:
      a.不能空字符串
      b.集合名不能含有\(zhòng)0【空字符】废亭,表示集合名的結(jié)尾
      c.集合名不能以"system."開頭古今,為系統(tǒng)集合保留的關(guān)鍵字
      d.不能含有保留字符,千萬不能含有$
    
    語法:
      // name的類型為String滔以,是要?jiǎng)?chuàng)建的集合的名稱
      // options的類型是Document捉腥,是一個(gè)文檔,指定相應(yīng)的大小和索引你画,是可選參數(shù)
      // 在插入文檔時(shí)抵碟,MongoDB首先檢查上限集合capped字段的大小,然后檢查max字段
      db.createCollection(name, options)
    
    例如:
      // 沒有options選項(xiàng)的集合創(chuàng)建
      db.createCollection("myCollection")
    
      // 有options選項(xiàng)的集合的創(chuàng)建
      db.createCollection("mycol",{capped:true,autoIndexId:true,size:1024,max:10000})
    
    
    選項(xiàng)列表
  • 顯示當(dāng)前數(shù)據(jù)庫中的集合

    show collections
    
    
  • 刪除集合

    語法:
      // 如果選定的集合成功刪除坏匪,drop()方法將返回true拟逮,否則返回false
      db.COLLECTION_NAME.drop()
    
    例如:
      db.mycollection.drop()
    
    

五、MongoDB之文檔操作

  • 文檔概念
    文檔:相當(dāng)表中的一條記錄【實(shí)體】
    是一組鍵值對(duì)适滓,文檔不需要設(shè)置相同的字段敦迄,并且相同的字段不需要相同的數(shù)據(jù)類型

    注意: 
    a.文檔中的鍵值對(duì)是有序的
    b.文檔中值除了字符串之外,還可以是其他數(shù)據(jù)類型【嵌套一個(gè)文檔】
    c.嚴(yán)格區(qū)分大小寫和數(shù)據(jù)類型的凭迹,mycol myCol
    d.文檔中不能有重復(fù)的鍵
    e.文檔中的鍵基本都是用字符串表示的
    
    
    文檔中鍵的命名:
    a.鍵不能包含\0
    b.$和.有特殊含義
    c.以下劃線開頭的鍵是保留的罚屋,盡量不要使用下劃線開頭
    
    
  • 插入文檔

    語法:
      // 在插入的文檔中,如果不指定_id參數(shù),那么 MongoDB 會(huì)為此文檔分配一個(gè)唯一的ObjectId
      // _id為集合中的每個(gè)文檔唯一的12個(gè)字節(jié)的十六進(jìn)制數(shù)。
      db.COLLECTION_NAME.insert(document)
    
    例如:
      // 插入一個(gè)
      db.mycol.insert({id:101, name:'lisi', age:20})
      db.mycol.insert({ 
         item: "canvas", 
         num: 100, 
         tags: ["cotton"], 
         size: { 
              h: 20,
              w: 30, 
          } 
      })
    
      // 插入多個(gè)(注意方括號(hào))
      db.mycol.insert( [{id:102, name:'wagnwu', age:18}, {id:103, name:'zhaoliu', age:21}, {id:104, name:'tianqi', age:19}] )
    
      // 查看已插入的文檔
      db.mycol.find()
      { "_id" : ObjectId("5b8b59cb5bd1df1fc73dcdc6"), "id" : 101, "name" : "lisi", "age" : 20 }
    
      // 查看已插入的文檔
      db.mycol.find().pretty()
      {
      "_id" : ObjectId("5b8b59cb5bd1df1fc73dcdc6"),
      "id" : 101,
      "name" : "lisi",
      "age" : 20
      }
    
    
  • 查詢文檔

    語法:
      // 基本操作
      db.COLLECTION_NAME.find(document)
       // 以格式化的方式返回查詢結(jié)果
       db.COLLECTION_NAME.find(document).pretty()
    
    注意: 
      find() 將以非結(jié)構(gòu)化的方式返回查詢結(jié)果
    
     例如: 
      // 顯示所有文檔
      db.mycol.find()
    
      // 默認(rèn)將所有文檔顯示嗤锉,為了限制列表,需要顯示的字段設(shè)置為1猛拴,不顯示的設(shè)置為0
      db.mycol.find( {'name':'liming'}, {'name':1, 'age': 1} )
      db.mycol.find( {'name':'liming'}, {'age':0} )
    
      // 限制字段顯示
      db.check.find({},{'_id':1,'title':1})
    
    
  • 查詢文檔(條件查詢)

    - 等于{ <key>:<value> }
      db.mycol.find({'name':'yhy'} ).pretty()
    
    - 小于 { <key>: {$lt:<value>} }
      db.mycol.find( {'age': {$lt:18}} ).pretty()
    
    - 小于等于 { <key>: {$lte:<value>} }
      db.mycol.find( {'age': {$lte:18}} ).pretty()
    
    - 大于 { <key>: {$gt:<value>} }
      db.mycol.find( {'age': {$gt:18}} ).pretty()
    
    - 大于等于 { <key>: {$gte:<value>} }
      db.mycol.find( {'age': {$gte:18}} ).pretty()
    
    - 不等于 { <key>: {$ne:<value>} }
      db.mycol.find( {'age': {$ne:18}} ).pretty()
    
    - 并列關(guān)系(and)
      在find()方法中,如果通過使用 ',' 將它們分開傳遞多個(gè)鍵蚀狰,則 MongoDB 將其視為AND條件
      db.mycol.find(
        {
          $and: [
            {key1: value1}, {key2: value2}
          ]
        }
      )
    
    - 或者關(guān)系(or)
      db.mycol.find(
        {
          $or: [
            {key1: value1}, {key2: value2}
          ]
        }
      )
    
    
  • 更新文檔

    update()更新現(xiàn)有文檔中的值,語法:
      db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)
    例如:
      // update默認(rèn)只更新一個(gè)文檔愉昆,如果要更新多個(gè)文檔,則添加參數(shù){multi:true})
      db.check.update( {'title': 'MongoDB Guide'}, {$set: {'title': 'mongo'}} )
      db.check.update( {'title': 'MongoDB Guide'}, {$set: {'title': 'mongo'}, $set: {'say': 'hello'}} )
      db.check.update( {'title': 'MongoDB Guide'}, {$set: {'title': 'mongo'}}, {multi: true} )
    
    save()用傳遞的文檔數(shù)據(jù)替換現(xiàn)有文檔麻蹋,語法:  
      db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA})
    例如:
      db.check.save( {'_id':102, 'title':'hello', 'by':'lalala'} )  
    
    
  • 刪除文檔

    語法:
      db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)
    
     例如:
       db.check.remove( {'_id':100} )
    
    

六跛溉、MongoDB之查詢

  • 投影
    查詢過程中,只顯示指定的字段

    語法:
      db.COLLECTION_NAME.find({},{KEY:1})
    
    例如:
      db.mycol.find( {}, {'title':1, _id:0} )
    
    

    在執(zhí)行find()方法時(shí)哥蔚,始終都會(huì)顯示_id字段倒谷,如果不想要此字段,則需要將其設(shè)置為0

  • 限制篩選記錄

    limit()限制MongoDB要返回的記錄數(shù),根據(jù)指定的參數(shù)返回記錄數(shù)
    語法:
      db.COLLECTION_NAME.find().limit(NUMBER)
    例如: 
      // 在查詢文檔時(shí)僅顯示兩個(gè)文檔
      db.mycol.find({},{"title":1,_id:0}).limit(2)
    
    skip() 方法跳過指定數(shù)量的數(shù)據(jù)
    語法:
      // 注意:skip()方法中的默認(rèn)值為0糙箍。
      db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
    例如:
      db.mycol.find({},{"title":1,_id:0}).limit(1).skip(2)
    
    
  • 對(duì)查詢記錄排序

     語法:
        // 使用指定順序進(jìn)行排序渤愁,1表示升序,-1表示降序
        db.COLLECTION_NAME.find().sort({KEY:1})
      例如:
         db.mycol.find({},{"title":1,_id:0}).sort({"title":-1})
    
    
  • 管道的概念
    MongoDB的聚合管道將MongoDB文檔在一個(gè)管道處理完畢后將結(jié)果傳遞給下一個(gè)管道處理深夯。管道操作是可以重復(fù)的抖格。

    $project:修改輸入文檔的結(jié)構(gòu)诺苹。可以用來重命名雹拄、增加或刪除域收奔,也可以用于創(chuàng)建計(jì)算結(jié)果以及嵌套文檔
      db.article.aggregate( [ {$project:{by_user:1, title:1}} ] )
    
    $limit:用來限制MongoDB聚合管道返回的文檔數(shù)
      db.article.aggregate( [ {$project:{by_user:1, title:1}}, {$limit: 2} ] )  
    
    $skip:在聚合管道中跳過指定數(shù)量的文檔,并返回余下的文檔
      db.article.aggregate( [ {$project:{by_user:1, title:1}}, {$skip: 1} ] )
      db.article.aggregate( [ {$project:{by_user:1, title:1}}, {$limit:2},{$skip: 1} ] ) 
    
    $group:將集合中的文檔分組滓玖,可用于統(tǒng)計(jì)結(jié)果
      db.article.aggregate( [ {$group: {_id:'$by_user', num:{$sum:'$likes'}}} ] )
    
    $sort:將輸入文檔排序后輸出
      db.article.aggregate( [ {$group: {_id:'$by_user', num:{$sum:'$likes'}}},{$sort: {'num':-1}} ] )
    
    
  • 分組與聚合函數(shù)查詢

    aggregate()語法:
      db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
    
    - $sum 從集合中的所有文檔中求出定義的值
      // 計(jì)算每個(gè)作者所寫的文章點(diǎn)贊數(shù)
      db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
      // 計(jì)算每個(gè)作者所寫文檔數(shù)量
      // select by_user, count(*) from article group by by_user
      db.article.aggregate([ { $group: {_id:'$by_user', num:{$sum:1}} } ])
    
    - $avg 計(jì)算集合中所有文檔的所有給定值的平均值
      db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
    
    - $max 從集合中的所有文檔獲取相應(yīng)值的最大值
      // _id:'$by_user'坪哄,對(duì)應(yīng)按照by_user分組
      db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
      // _id對(duì)應(yīng)一個(gè)常量,即所有數(shù)據(jù)的操作
      db.article.aggregate([ { $group:{_id:'max', num_likes:{$max:'$likes'}} } ])
    
    - $min 從集合中的所有文檔獲取相應(yīng)值的最小值
      db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
    
    - 例如:
      db.article.aggregate([{$group:{'_id':'$by_user','num_tutorial':{$sum:1}}}])
    
    

七势篡、MongoDB之關(guān)聯(lián)關(guān)系

MongoDB中的關(guān)系表示各個(gè)文檔在邏輯上的相互關(guān)聯(lián)翩肌。關(guān)系可以通過嵌入式和引用方法建模。 這種關(guān)系可以是1:1禁悠,1:N念祭,N:1或N:N。

假設(shè)有一種情況:要存儲(chǔ)用戶的地址碍侦。一個(gè)用戶可以擁有多個(gè)地址粱坤,這就是1:N關(guān)系。

// 用戶user文檔
{
   "_id":10999110,
   "name": "Maxsu",
   "contact": "13800138000",
   "dob": "1992-10-11"
}

// 地址文檔
{
   "_id":12200,
   "building": "Hainan Building NO.2100",
   "pincode": 571100,
   "city": "Haikou",
   "province": "Hainan"
}

嵌入式關(guān)系建模
在嵌入式方法中瓷产,我們將地址(address)文檔嵌入到用戶(user)文檔中

{
   "_id": 21000100,
   "contact": "13800138000",
   "dob": "1991-11-11",
   "name": "Maxsu",
   "address": [
      {
         "building": "Hainan Building NO.2100",
         "pincode": 571100,
         "city": "Haikou",
         "province": "Hainan"
      },
      {
         "building": "Sanya Building NO.2100",
         "pincode": 572200,
         "city": "Sanya",
         "province": "Hainan"
      },
   ]
}

該方法將所有相關(guān)數(shù)據(jù)保存在單個(gè)文檔中站玄,這使得檢索和維護(hù)更容易。
可以使用單個(gè)查詢來在整個(gè)文檔檢索:
 db.users.find( {"name":"Maxsu"},{"address":1, "name":1} )

在上述查詢中拦英,db和users分別是數(shù)據(jù)庫和集合蜒什。缺點(diǎn)是如果嵌入式文檔的大小如果不斷增長,可能會(huì)影響讀/寫性能疤估。

建模參考關(guān)系
這是設(shè)計(jì)規(guī)范化關(guān)系的方法。 
在這種方法中霎冯,用戶和地址文件將分別維護(hù)铃拇,但用戶文檔將包含一個(gè)將引用地址文檔的id字段的字段。
{
   "_id":ObjectId("52ffc33321332111sdfaf"),
   "contact": "13800138000",
   "dob": "1991-11-11",
   "name": "Maxsu",
   "address_ids": [
      ObjectId("123123"),
      ObjectId("123412")
   ]
}
用戶文檔包含對(duì)應(yīng)地址的ObjectId的數(shù)組字段address_ids沈撞。 
使用這些ObjectIds慷荔,我們可以從那里查詢地址文件并獲取地址詳細(xì)信息。 
使用這種方法缠俺,需要兩個(gè)查詢:首先從用戶文檔獲取address_ids字段显晶,然后從地址集中獲取這些地址。
var result = db.users.find({"name":"Maxsu"},{"address_ids":1})
var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})

八壹士、MongoDB與Python的交互

- 安裝
pip3 install pymongo

- 使用
import pymongo
from pymongo import  MongoClient
from bson.objectid import ObjectId

#1.建立連接
#創(chuàng)建MongoClient的對(duì)象
#方式一
#特點(diǎn):可以連接默認(rèn)的主機(jī)和端口號(hào)
#client = MongoClient()
#方式二
#明確指明主機(jī)和端口號(hào)
#client = MongoClient('localhost',27017)
#client = MongoClient(host='localhost',port=27017)
#方式三
#使用MongoDB URI的
client = MongoClient('mongodb://localhost:27017')

#2.獲取數(shù)據(jù)庫
#MongoDB的一個(gè)實(shí)例可以支持多個(gè)獨(dú)立的數(shù)據(jù)庫
#可以通過MongoClient的對(duì)象的屬性來訪問數(shù)據(jù)庫
#方式一
db = client.test
print(db)
#方式二
#db = client['test']

#3.獲取集合
#集合是存儲(chǔ)在MongoDb中的一組文檔磷雇,可以類似于MySQl中的表
#方式一
collection = db.stuents
#方式二
#collection = db['students']
"""
注意:
MongoDB中關(guān)于數(shù)據(jù)庫和集合的創(chuàng)建都是懶創(chuàng)建
以上的操作在MongoDB的服務(wù)端沒有做任何操作
當(dāng)?shù)谝粋€(gè)文檔被插入集合的時(shí)候才會(huì)創(chuàng)建數(shù)據(jù)庫和集合
"""

#4.文檔
#在pymongo中使用字典來表示文檔
student1 = {
    'id':'20180101',
    'name':'jack',
    'age':20,
    'gender':'male'
}

#5.插入文檔
#5.1insert()
#插入單條數(shù)據(jù)
#注意:MongoDb會(huì)自動(dòng)生成一個(gè)ObjectId,insert函數(shù)的返回值為objectid
result = collection.insert(student1)
print(result)

#插入多條數(shù)據(jù)
student2 = {
    'id':'20180530',
    'name':'tom',
    'age':30,
    'gender':'male'
}
student3 = {
    'id':'20180101',
    'name':'bob',
    'age':18,
    'gender':'male'
}
#result = collection.insert([student2,student3])

#6.查詢文檔
#6.1
#find_one()
result = collection.find_one({'name':'jack'})
print(type(result))    #<class 'dict'>
print(result)

#6.2find()
#需求:查詢年齡為20的數(shù)據(jù)
results = collection.find({'age':20})
print(results)
#Cursor相當(dāng)于是一個(gè)生成器,只能通過遍歷的方式獲取其中的數(shù)據(jù)
for r in results:
    print(r)

#6.3其他用法
#a.count()
#統(tǒng)計(jì)所有數(shù)據(jù)的條數(shù)
count1 = collection.find().count()
#統(tǒng)計(jì)制定條件的數(shù)據(jù)條數(shù)
count1 = collection.find({'age':20}).count()

#7.更新文檔
#7.1update()
conditon = {'name':'jack'}
student = collection.find_one(conditon);
student['age'] = 30
result = collection.update(conditon,student)

#7.2update_one()
conditon = {'name':'jack'}
student = collection.find_one(conditon);
student['age'] = 30
result = collection.update_one(conditon,{'$set':student})
print(result.matched_count,result.modified_count)

#7.3update_many()
#查詢年齡大于20的數(shù)據(jù)躏救,然后講年齡增加1
conditon = {'age':{'$gt':20}}
result = collection.update_one(conditon,{'$inc':{'age':1}})
print(result.matched_count,result.modified_count)

#8.刪除文檔
#8.1remove()
#將符合條件的所有的數(shù)據(jù)全部刪除
result = collection.remove({'name':'rose'})

#8.2delete_one()
result = collection.delete_one({'name':'rose'})

#8.3delete_many()
result = collection.delete_many({'name':'rose'})

備注: 默認(rèn)MongoDB是綁定127.0.0.1唯笙,連接遠(yuǎn)程是連接不了的螟蒸。
編輯MongoDB配置文件: sudo vi /etc/mongodb.conf
找到 bind_ip = 127.0.0.1 改為 bind_ip = 0.0.0.0

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市崩掘,隨后出現(xiàn)的幾起案子七嫌,更是在濱河造成了極大的恐慌,老刑警劉巖苞慢,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诵原,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡挽放,警方通過查閱死者的電腦和手機(jī)皮假,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骂维,“玉大人惹资,你說我怎么就攤上這事『焦耄” “怎么了褪测?”我有些...
    開封第一講書人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長潦刃。 經(jīng)常有香客問我侮措,道長,這世上最難降的妖魔是什么乖杠? 我笑而不...
    開封第一講書人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任分扎,我火速辦了婚禮,結(jié)果婚禮上胧洒,老公的妹妹穿的比我還像新娘畏吓。我一直安慰自己,他們只是感情好卫漫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開白布菲饼。 她就那樣靜靜地躺著,像睡著了一般列赎。 火紅的嫁衣襯著肌膚如雪宏悦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評(píng)論 1 305
  • 那天包吝,我揣著相機(jī)與錄音饼煞,去河邊找鬼。 笑死诗越,一個(gè)胖子當(dāng)著我的面吹牛砖瞧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掺喻,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芭届,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼储矩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起褂乍,我...
    開封第一講書人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤持隧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后逃片,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屡拨,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年褥实,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了呀狼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡损离,死狀恐怖哥艇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情僻澎,我是刑警寧澤貌踏,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站窟勃,受9級(jí)特大地震影響祖乳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秉氧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一眷昆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汁咏,春花似錦亚斋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至轰驳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弟灼,已是汗流浹背级解。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留田绑,地道東北人勤哗。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像掩驱,于是被迫代替她去往敵國和親芒划。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冬竟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一、MongoDB簡介 概述MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫民逼,由C++語言編寫泵殴。旨在為WEB應(yīng)用提供...
    EndEvent閱讀 1,163評(píng)論 1 4
  • 一、MongoDB簡介 概述MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫拼苍,由C++語言編寫笑诅。旨在為WEB應(yīng)用提供...
    王梓懿_1fbc閱讀 493評(píng)論 0 3
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,938評(píng)論 2 89
  • 一、MongoDB簡介 概述MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫疮鲫,由C++語言編寫吆你。旨在為WEB應(yīng)用提供...
    fly5閱讀 286評(píng)論 0 0
  • 一、MongoDB簡介 概述MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫俊犯,由C++語言編寫妇多。旨在為WEB應(yīng)用提供...
    未央_m閱讀 712評(píng)論 0 1