Python | Python交互之mongoDB交互詳解

Python | Python交互之mongoDB交互詳解

前言


本篇爲mongodb篇,包含實例演示,mongodb高級查詢,mongodb聚合管道,python交互等內容。python

mongoDB的優點


  • 易擴展mysql

  • 大數據量,高性能正則表達式

  • 靈活的數據模型

安裝與啓動


安裝mongodb:sudo apt-get install -y mongodb-org
安裝可視化管理界面:https://robomongo.org/downloadsql

查看幫助:mongod –help
啓動服務:sudo service mongod start
中止服務:sudo service mongod stop
重啓服務:sudo service mongod restart
查看進程:ps ajx|grep mongodmongodb

配置文件的位置:/etc/mongod.conf
默認端口:27017
日誌的位置:/var/log/mongodb/mongod.log數據庫

mongodb數據庫操做


數據庫操做

查看當前的數據庫:db
查看全部的數據庫:show dbs /show databases
切換數據庫:use db_name
刪除當前的數據庫:db.dropDatabase()數組

集合操做

當集合不存在時,插入任何一條數據集合自動建立。
或者手動建立集合:db.createCollection(name,[options])
其中options:服務器

參數capped: 默認值爲false表示不設置上限,值爲true表示設置上限

參數size: 當capped值爲true時,須要指定此參數,表示上限大小,當文檔達到上限時,會將以前的數據覆蓋,單位爲字節

當集合存在時:
查看集合:show collections
刪除集合:db.集合名稱.drop()app

mongodb數據類型


Object ID:文檔IDless

String: 字符串,最常使用,必須是有效的UTF-8

Boolean: 存儲一個布爾值,true或false

Integer: 整數能夠是32位或64位,這取決於服務器

Double: 存儲浮點值

Arrays: 數組或列表, 多個值存儲到一個鍵

Object: 用於嵌入式的文檔, 即一個值爲一個文檔

Null: 存儲Null值

Timestamp: 時間戳,表示從1970-1-1到如今的總秒數

Date: 存儲當前日期或時間的UNIX時間格式

注意點:

建立日期語句以下 :參數的格式爲YYYY-MM-DD
                new Date('2017-12-20')

每一個文檔都有一個屬性,爲_id,保證每一個文檔的惟一性
能夠本身去設置_id插入文檔,若是沒有提供,那麼MongoDB爲每一個⽂檔提供了一個獨特的_id,類型爲objectID

objectID是一個12字節的十六進制數:
前4個字節爲當前時間戳
接下來3個字節的機器ID
接下來的2個字節中MongoDB的服務進程id
最後3個字節是簡單的增量值

mongodb數據操做


新增

插入數據(字段_id存在就報錯):db.集合名稱.insert(document)

插入數據(字段_id存在就更新):db.集合名稱.save(document)

舉個栗子:

#插入文檔時,若是不指定_id參數,MongoDB會爲文檔分配一個惟一的ObjectId
db.xianyu.insert({name:"xianyuplus",age:"3"})

#插入文檔時,能夠指定_id參數
db.xianyu.insert({_id:"10001",name:"xianyuplus",age:"30"})

#更新了上面_id爲1001的文檔
db.xianyu.save({_id:"10001",name:"xianyuplus",age:"40"})

查詢

查詢數據:db.集合名稱.find()

舉個栗子:

db.xianyu.find()

更新

更新數據:db.集合名稱.update(<query> ,<update>,{multi: <boolean>})

參數query:查詢條件

參數update:更新操做符

參數multi:可選,默認是false,表示只更新找到的第一條記錄,值爲true表示把知足條件的文檔所有更新

舉個栗子:

原有內容:
{
    "_id" : ObjectId("5b66f05f1194e110103bc283"),
    "name": "xianyuplus",
    "age": "40"
    }

# 將name爲xianyuplus的值替換爲xianyuplus1
db.xianyu.update({name:"xianyuplus"},{name:"xianyuplus1"})

操做後內容:
{
    "_id" : ObjectId("5b66f05f1194e110103bc283"),
    "name": "xianyuplus1"
    }

能夠看到單單使用update更新數據會致使原有數據被新數據替換,因此咱們應該搭配$set使用,指定更新對應的鍵值。

舉個栗子:

原有內容:
{
    "_id" : ObjectId("5b66f05f1194e110103bc283"),
    "name": "xianyuplus",
    "age": "40"
    }
# 將name爲xianyuplus的值更新爲xianyuplus1
db.xianyu.update({name:"xianyuplus"},{$set:{name:"xianyuplus1"}})

操做後內容:
{
    "_id" : ObjectId("5b66f05f1194e110103bc283"),
    "name": "xianyuplus1",
    "age": "40"
    }

更新多條數據:使用參數multi:true

舉個栗子:

# 更新所有數據的name值爲xianyuplus1
db.stu.update({},{$set:{name:"xianyuplus1"}},{multi:true})

注意:multi update only works with $ operators 即multi只要和$搭配使用時才能起效。

刪除

刪除數據:db.集合名稱.remove(<query>,{justOne: <boolean>})

參數query:可選,刪除的文檔的條件

參數justOne:可選,若是設爲true或1,則只刪除一條,默認fals,表示刪除多條

舉個栗子:

# 把name值爲xianyuplus的數據所有刪掉
db.xianyu.remove({name:"xianyuplus"})

mongodb高級查詢


mongodb查詢方法

查詢文檔:db.集合名稱.find({條件文檔})
查詢一條數據:db.集合名稱.findOne({條件文檔})
格式化查詢:db.集合名稱.find({條件文檔}).pretty()

舉個栗子:

# 查詢name爲xianyuplus的數據
db.xianyu.find({name:"xianyuplus"})

# 查詢一條name爲xianyuplus的數據
db.xianyu.findOne({name:"xianyuplus"})

mongodb的比較運算符

等於:如上述栗子
大於:$gt ( greater than )
大於等於:$gte ( greater than equal )
小於:$lt ( less than )
小於等於:$lte ( less than equal )
不等於:$nt ( not equal )

舉個栗子:

# 查詢age大於20的數據
db.xianyu.find({age:{$gt:20}})

# 查詢age大於等於20的數據
db.xianyu.find({age:{$gte:20}})

# 查詢age小於20的數據
db.xianyu.find({age:{$lt:20}})

# 查詢age小於等於20的數據
db.xianyu.find({age:{$lte:20}})

# 查詢age不等於20的數據
db.xianyu.find({age:{$ne:20}})

mongodb邏輯運算符

and:在find條件文檔中寫入多個字段條件便可
or:使用$or

舉個栗子:

#查找name爲xianyuplus且age爲20的數據
db.xianyu.find({name:"xianyuplus",age:20})

#查找name爲xianyuplus或age爲20的數據
db.xianyu.find({$or:[{name:"xianyuplus"},{age:20}]})

#查找name爲xianyuplus或age大於20的數據
db.xianyu.find({$or:[{age:{$gt:20}},{name:"xianyuplus"}]})

#查找age大於等於20或gender爲男而且name爲xianyuplus的數據
db.xianyu.find({$or:[{gender:"true"},{age:{$gte:18}}],name:"xianyuplus"})

mongodb範圍運算符

使用$in與$nin判斷是否在某一範圍內

舉個栗子:

#查詢年齡爲1八、28的數據
db.xianyu.find({age:{$in:[]18,28}})

mongodb使用正則表達式

使用//或$regex編寫正則表達式

舉個栗子:

# 查詢name以xian開頭的數據
db.xianyu.find({name:/^xianyu/})
db.xianyu.find({name:{$regex:'^xianyu'}})

mongodb分頁與跳過

查詢前n條數據:db.集合名稱.find().limit(NUMBER)

跳過n條數據:db.集合名稱.find().skip(NUMBER)

舉個栗子:

#查詢前3條數據
db.xianyu.find().limit(3)

#查詢3條後的數據
db.xianyu.find().skip(3)

#skip和limit能夠搭配使用,查詢4,5,6條數據
db.xianyu.find().skip(3).limit(3)

mongodb自定義查詢

使用$where自定義查詢,這裏使用的是js語法

舉個栗子:

//查詢age大於30的數據
db.xianyu.find({
    $where:function() {
        return this.age>30;}
})

mongodb投影

投影:在查詢結果中只顯示你想要看到的數據字段內容。

db.集合名稱.find({},{字段名稱:1,...})

想顯示的字段設置爲1,不想顯示的字段不設置,而_id這個字段比較特殊,想要他不顯示須要設置_id爲0。

#查詢結果中只顯示name字段,不顯示age
db.xianyu.find({},{name:1})

mongodb排序

排序:db.集合名稱.find().sort({字段:1,...})

將須要排序的字段設置值:升序爲1,降序爲-1

舉個栗子:

#先按照性別降序排列再按照年齡升序排列
db.xianyu.find().sort({gender:-1,age:1})

mongodb計數

統計數目:db.集合名稱.find({條件}).count()
db.集合名稱.count({條件})

舉個栗子:

#查詢age爲20的數據個數
db.xianyu.find({age:20}).count()
#查詢age大於20,且性別爲nan的數據個數
db.xianyu.count({age:{$gt:20},gender:true})

mongodb去重

去重:db.集合名稱.distinct('去重字段',{條件})

舉個栗子:

#去除家鄉相同,且年齡大於18的數據
db.xianyu.distinct('hometown',{age:{$gt:18}})

mongodb管道與聚合


聚合(aggregate)是基於數據處理的聚合管道,每一個文檔經過一個由多個階段(stage)組成的管道,能夠對每一個階段的管道進行分組、過濾等功能,而後通過一系列的處理,輸出相應的結果。

用法:db.集合名稱.aggregate({管道:{表達式}})

經常使用管道:

$group: 將集合中的文檔分組, 可用於統計結果
$match: 過濾數據, 只輸出符合條件的文檔
$project: 修改輸出文檔的結構, 如重命名、 增長、 刪除字段、 建立計算結果
$sort: 將輸出文檔排序後輸出
$limit: 限制聚合管道返回的文檔數
$skip: 跳過指定數量的文檔, 並返回餘下的文檔
$unwind: 將數組類型的字段進行拆分

經常使用表達式:表達式:"列名"

$sum: 計算總和, $sum:1 表示以一倍計數
$avg: 計算平均值
$min: 獲取最小值
$max: 獲取最大值
$push: 在結果文檔中插入值到一個數組中
$first: 根據資源文檔的排序獲取第一個文檔數據
$last: 根據資源文檔的排序獲取最後一個文檔數據

聚合之$group

group:將文檔進行分組以便於統計數目

用法:_id表示分組依據,_id:"$字段名"

舉個栗子:

#按照hometown分組,並計數
db.xianyu.aggregate({$group:{_id:"$hometown", count:{$sum:1}}})

#將集合中全部的內容分爲一組,統計個數
db.xianyu.aggregate({$group:{_id:null, count:{$sum:1}}})

聚合之$project

project:修改輸入文檔的結構,如:重命名,增長、刪除字段等

舉個栗子:

#按照hometown分組,並計數
#分組輸出,只顯示count字段
 db.xianyu.aggregate(
        {$group:{_id:"$hometown", count:{$sum:1}}},
        {$project:{_id:0,count:1}}
 )

聚合之$match

match:用於過濾數據,只輸出符合條件的文檔,功能和find相似,可是match是管道命令,能將結果交給後一個管道,可是find不能夠。

舉個栗子:

#查詢age大於20
#按照hometown分組,並計數
#分組輸出,只顯示count字段
 db.xianyu.aggregate(
        {$match:{age:{$gte:20}}},
        {$group:{_id:"$hometown", count:{$sum:1}}},
        {$project:{_id:0,count:1}}
 )

聚合之$sort

sort:將輸入文檔排序後輸出

舉個栗子:

#查詢age大於20
#按照hometown分組,並計數
#分組輸出,只顯示count字段
#按照計數升序排序
 db.xianyu.aggregate(
        {$match:{age:{$gte:20}}},
        {$group:{_id:"$hometown", count:{$sum:1}}},
        {$project:{_id:0,count:1}},
        {$sort:{count:1}}
 )

聚合之$limit與$skip

limit:限制聚合管道返回的文檔數

skip:跳過指定數量的文檔數,返回剩下的文檔

舉個栗子:

#查詢age大於20
#按照hometown分組,並計數
#按照計數升序排序
#跳過前一個文檔,返回第二個
 db.xianyu.aggregate(
        {$match:{age:{$gte:20}}},
        {$group:{_id:"$hometown", count:{$sum:1}}},
        {$sort:{count:1}},
        {$skip:1},
        {$limit:1}
 )

聚合之$unwind

unwind:將文檔中的某一個數組類型字段拆分紅多條, 每條包含數組中的一個值

db.集合名稱.aggregate({$unwind:'$字段名稱'})

舉個栗子:

db.xianyu.insert({_id:1,item:'t-shirt',size:['S','M','L']})
db.xianyu.aggregate({$unwind:'$size'})
輸出:
{ "_id" : 1, "item" : "t-shirt", "size" : "S" }
{ "_id" : 1, "item" : "t-shirt", "size" : "M" }
{ "_id" : 1, "item" : "t-shirt", "size" : "L" }

聚合使用注意事項

  • $group對應的字典中有幾個鍵,結果中就有幾個鍵

  • 分組依據須要放到_id後面

  • 取不一樣的字段的值須要使用$,$gender,$age

  • 取字典嵌套的字典中的值的時候$_id.country

  • 可以同時按照多個鍵進行分組
    {$group:{_id:{country:"$字段",province:"$字段"}}}

mongodb索引


用法:db.集合.ensureIndex({屬性:1}),1表示升序, -1表示降序

建立惟一索引:db.集合.ensureIndex({"屬性":1},{"unique":true})
建立惟一索引並消除:
db.集合.ensureIndex({"屬性":1},{"unique":true,"dropDups":true})

創建聯合索引:db.集合.ensureIndex({屬性:1,age:1})
查看當前集合的全部索引:db.集合.getIndexes()
刪除索引:db.集合.dropIndex('索引名稱')

mongodb數據備份與恢復


mongodb數據備份

備份:mongodump -h dbhost -d dbname -o dbdirectory

-h: 服務器地址,也能夠指定端口號
-d: 須要備份的數據庫名稱
-o: 備份的數據存放位置,此目錄中存放着備份出來的數據

mongodb數據恢復

恢復:mongorestore -h dbhost -d dbname --dir dbdirectory

-h: 服務器地址
-d: 須要恢復的數據庫實例
--dir: 備份數據所在位置

mongodb與python交互


安裝與導入

安裝:pip install pymongo
導入模塊:from pymongo import MongoClient

實例化

實例化對象以連接數據庫,鏈接對象有host,port兩個參數。

from pymongo import MongoClient
class clientMongo:
    def __init__(self):
      client = MongoClient(host="127.0.0.1", port=27017)
      #使用[]括號的形式選擇數據庫和集合
      self.cliention = client["xianyu"]["xianyuplus"]

插入數據

插入單條數據:返回ObjectId

def item_inser_one(self):
  ret = self.cliention.insert({"xianyu":"xianyuplus","age":20})
  print(ret)

插入多條數據:

def item_insert_many(self):
  item_list = [{"name":"xianyuplus{}".format(i)} for i in range(10000)]
  items = self.cliention.insert_many(item_list)

查詢數據

查詢單條數據:

def item_find_one(self):
  ret = self.cliention.find_one({"xianyu":"xianyuplus"})
  print(ret)

查詢多條數據:

def item_find_many(self):
ret = self.cliention.find({"xianyu":"xianyuplus"})
for i in ret:
print(i)

更新數據

更新一條數據:

def item_update_one(self):
  self.cliention.update_one({"xianyu":"xianyuplus"},{"$set":{"xianyu":"xianyu"}})

更新所有數據:

def item_update(self):
  self.cliention.update_many({"xianyu":"xianyuplus"},{"$set":{"xianyu":"xianyu"}})

刪除數據

刪除一條數據:

def item_delete_one(self):
  self.cliention.delete_one({"xianyu":"xianyuplus"})

刪除符合條件的數據:

def item_delete_many(self):
  self.cliention.delete_many({"xianyu":"xianyuplus"})

尾言


以上就是關於mongodb的一些用法,重點部分仍是mongo高級查詢以及聚合管道,必定要review幾遍才記得住,本篇是python數據庫交互的最後一篇,但願對你有所幫助。

推薦閱讀


Python | Python學習之Redis交互詳解

Python | Python學習之mysql交互詳解