新聞推薦實(shí)戰(zhàn)(二):MongoDB基礎(chǔ)
本文屬于新聞推薦實(shí)戰(zhàn)—數(shù)據(jù)層—構(gòu)建物料池之MongoDB。
MongoDB數(shù)據(jù)庫(kù)在該項(xiàng)目中會(huì)用來(lái)存儲(chǔ)畫像數(shù)據(jù)(用戶畫像、新聞畫像),使用MongoDB存儲(chǔ)畫像的一個(gè)主要原因就是方便擴(kuò)展,因?yàn)楫嬒駜?nèi)容可能會(huì)隨著產(chǎn)品的不斷發(fā)展而不斷的更新。作為算法工程師需要了解常用的MongoDB語(yǔ)法(比如增刪改查,排序等),因?yàn)樵趯?shí)際的工作可能會(huì)從MongoDB中獲取用戶、新聞畫像來(lái)構(gòu)造相關(guān)特征。本著這個(gè)目的,本文對(duì)MongoDB常見(jiàn)的語(yǔ)法及Python操作MongoDB進(jìn)行了總結(jié),方便大家快速了解。
主要特點(diǎn)
創(chuàng)建數(shù)據(jù)庫(kù)目錄
MongoDB 后臺(tái)管理 Shell
MongoDB 創(chuàng)建數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)
語(yǔ)法
實(shí)例
MongoDB 創(chuàng)建集合
實(shí)例
MongoDB 刪除集合
實(shí)例
MongoDB 插入文檔
插入文檔
實(shí)例
MongoDB 更新文檔
update() 方法
實(shí)例
MongoDB 刪除文檔
語(yǔ)法
實(shí)例
MongoDB 查詢文檔
語(yǔ)法
實(shí)例
MongoDB AND 條件
MongoDB OR 條件
AND 和 OR 聯(lián)合使用
MongoDB 排序
MongoDB sort() 方法
PyMongo
pip 安裝
測(cè)試 PyMongo
創(chuàng)建數(shù)據(jù)庫(kù)
創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)
判斷數(shù)據(jù)庫(kù)是否已存在
創(chuàng)建集合
創(chuàng)建一個(gè)集合
判斷集合是否已存在
Python Mongodb 插入文檔
插入集合
插入多個(gè)文檔
Python Mongodb 查詢文檔
查詢一條數(shù)據(jù)
查詢集合中所有數(shù)據(jù)
查詢指定字段的數(shù)據(jù)
根據(jù)指定條件查詢
返回指定條數(shù)記錄
Python Mongodb 修改文檔
排序
Python Mongodb 刪除數(shù)據(jù)
刪除集合中的所有文檔
刪除集合
MongoDB簡(jiǎn)介
MongoDB 是由C++語(yǔ)言編寫的,是一個(gè)基于分布式文件存儲(chǔ)的開(kāi)源數(shù)據(jù)庫(kù)系統(tǒng)。在高負(fù)載的情況下,添加更多的節(jié)點(diǎn),可以保證服務(wù)器性能。MongoDB 旨在為WEB應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案。
MongoDB 將數(shù)據(jù)存儲(chǔ)為一個(gè)文檔,數(shù)據(jù)結(jié)構(gòu)由鍵值(key=>value)對(duì)組成。MongoDB 文檔類似于 JSON 對(duì)象。字段值可以包含其他文檔,數(shù)組及文檔數(shù)組。

主要特點(diǎn)
MongoDB 是一個(gè)面向文檔存儲(chǔ)的數(shù)據(jù)庫(kù),操作起來(lái)比較簡(jiǎn)單和容易。 你可以在MongoDB記錄中設(shè)置任何屬性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")來(lái)實(shí)現(xiàn)更快的排序。 你可以通過(guò)本地或者網(wǎng)絡(luò)創(chuàng)建數(shù)據(jù)鏡像,這使得MongoDB有更強(qiáng)的擴(kuò)展性。 如果負(fù)載的增加(需要更多的存儲(chǔ)空間和更強(qiáng)的處理能力) ,它可以分布在計(jì)算機(jī)網(wǎng)絡(luò)中的其他節(jié)點(diǎn)上這就是所謂的分片。 Mongo支持豐富的查詢表達(dá)式。查詢指令使用JSON形式的標(biāo)記,可輕易查詢文檔中內(nèi)嵌的對(duì)象及數(shù)組。 MongoDb 使用update()命令可以實(shí)現(xiàn)替換完成的文檔(數(shù)據(jù))或者一些指定的數(shù)據(jù)字段 。 Mongodb中的Map/reduce主要是用來(lái)對(duì)數(shù)據(jù)進(jìn)行批量處理和聚合操作。 Map和Reduce。Map函數(shù)調(diào)用emit(key,value)遍歷集合中所有的記錄,將key與value傳給Reduce函數(shù)進(jìn)行處理。 Map函數(shù)和Reduce函數(shù)是使用Javascript編寫的,并可以通過(guò)db.runCommand或mapreduce命令來(lái)執(zhí)行MapReduce操作。 GridFS是MongoDB中的一個(gè)內(nèi)置功能,可以用于存放大量小文件。 MongoDB允許在服務(wù)端執(zhí)行腳本,可以用Javascript編寫某個(gè)函數(shù),直接在服務(wù)端執(zhí)行,也可以把函數(shù)的定義存儲(chǔ)在服務(wù)端,下次直接調(diào)用即可。 MongoDB支持各種編程語(yǔ)言:RUBY,PYTHON,JAVA,C++,PHP,C#等多種語(yǔ)言。 MongoDB安裝簡(jiǎn)單
Linux平臺(tái)安裝MongoDB
MongoDB 提供了 linux 各個(gè)發(fā)行版本 64 位的安裝包,你可以在官網(wǎng)下載安裝包。
MongoDB 源碼下載地址:https://www.mongodb.com/download-center#community
安裝前我們需要安裝各個(gè) Linux 平臺(tái)依賴包。
Red Hat/CentOS:
sudo?yum?install?libcurl?openssl
Ubuntu 18.04 LTS ("Bionic")/Debian 10 "Buster":
sudo?apt-get?install?libcurl4?openssl
Ubuntu 16.04 LTS ("Xenial")/Debian 9 "Stretch":
sudo?apt-get?install?libcurl3?openssl
查看ubuntu的版本
lsb_release?-a



這里我們選擇 tgz 下載,下載完安裝包,并解壓 tgz(以下演示的是 64 位 Linux上的安裝) 。
wget?https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-4.4.10.tgz?#下載
tar?-zxvf?mongodb-linux-x86_64-ubuntu1604-4.4.10.tgz?#解壓
MongoDB 的可執(zhí)行文件位于 bin 目錄下,所以可以將其添加到 PATH 路徑中
export?PATH=/bin:$PATH
**
創(chuàng)建數(shù)據(jù)庫(kù)目錄
默認(rèn)情況下 MongoDB 啟動(dòng)后會(huì)初始化以下兩個(gè)目錄:
數(shù)據(jù)存儲(chǔ)目錄:/var/lib/mongodb 日志文件目錄:/var/log/mongodb
我們?cè)趩?dòng)前可以先創(chuàng)建這兩個(gè)目錄:
sudo?mkdir?-p?/var/lib/mongo
sudo?mkdir?-p?/var/log/mongodb
接下來(lái)啟動(dòng) Mongodb 服務(wù):
mongod?--dbpath?/var/lib/mongo?--logpath?/var/log/mongodb/mongod.log?--fork
MongoDB 后臺(tái)管理 Shell
如果你需要進(jìn)入 mongodb 后臺(tái)管理,由于已經(jīng)將MongoDB可執(zhí)行文件添加到PATH路徑,所以可以直接執(zhí)行 mongo 命令文件。
MongoDB Shell 是 MongoDB 自帶的交互式 Javascript shell,用來(lái)對(duì) MongoDB 進(jìn)行操作和管理的交互式環(huán)境。
當(dāng)你進(jìn)入 mongoDB 后臺(tái)后,它默認(rèn)會(huì)鏈接到 test 文檔(數(shù)據(jù)庫(kù)):

MongoDB 概念解析
在mongodb中基本的概念是文檔、集合、數(shù)據(jù)庫(kù)。下表將幫助您更容易理解Mongo中的一些概念:
| SQL術(shù)語(yǔ)/概念 | MongoDB術(shù)語(yǔ)/概念 | 解釋/說(shuō)明 |
|---|---|---|
| database | database | 數(shù)據(jù)庫(kù) |
| table | collection | 數(shù)據(jù)庫(kù)表/集合 |
| row | document | 數(shù)據(jù)記錄行/文檔 |
| column | field | 數(shù)據(jù)字段/域 |
| index | index | 索引 |
| table joins | 表連接,MongoDB不支持 | |
| primary key | primary key | 主鍵,MongoDB自動(dòng)將_id字段設(shè)置為主鍵 |
MongoDB 創(chuàng)建數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)
一個(gè)mongodb中可以建立多個(gè)數(shù)據(jù)庫(kù)。
MongoDB的默認(rèn)數(shù)據(jù)庫(kù)為"db",該數(shù)據(jù)庫(kù)存儲(chǔ)在data目錄中。
MongoDB的單個(gè)實(shí)例可以容納多個(gè)獨(dú)立的數(shù)據(jù)庫(kù),每一個(gè)都有自己的集合和權(quán)限,不同的數(shù)據(jù)庫(kù)也放置在不同的文件中。
"show dbs" 命令可以顯示所有數(shù)據(jù)的列表。
toby@recsys:~$?mongo
MongoDB?shell?version:?2.6.10
connecting?to:?test
>?show?dbs
admin??(empty)
local??0.078GB
執(zhí)行 "db" 命令可以顯示當(dāng)前數(shù)據(jù)庫(kù)對(duì)象或集合。
toby@recsys:~$?mongo
MongoDB?shell?version:?2.6.10
connecting?to:?test
>?db
test
運(yùn)行"use"命令,可以連接到一個(gè)指定的數(shù)據(jù)庫(kù)。
toby@recsys:~$?mongo
MongoDB?shell?version:?2.6.10
connecting?to:?test
>?use?admin
switched?to?db?admin
>?db
admin
>?
語(yǔ)法
MongoDB 創(chuàng)建數(shù)據(jù)庫(kù)的語(yǔ)法格式如下:
use?DATABASE_NAME
如果數(shù)據(jù)庫(kù)不存在,則創(chuàng)建數(shù)據(jù)庫(kù),否則切換到指定數(shù)據(jù)庫(kù)。
實(shí)例
以下實(shí)例我們創(chuàng)建了數(shù)據(jù)庫(kù) tobytest:
toby@recsys:~$?mongo
MongoDB?shell?version:?2.6.10
connecting?to:?test
>?use?tobytest
switched?to?db?tobytest
>?db
tobytest
>?
如果你想查看所有數(shù)據(jù)庫(kù),可以使用 show dbs 命令:
>?show?dbs
admin??(empty)
local??0.078GB
>?
可以看到,我們剛創(chuàng)建的數(shù)據(jù)庫(kù) tobytest并不在數(shù)據(jù)庫(kù)的列表中, 要顯示它,我們需要向 tobytest數(shù)據(jù)庫(kù)插入一些數(shù)據(jù)。
>?db.tobytest.insert({"name":"Toby"})
WriteResult({?"nInserted"?:?1?})
>?show?dbs
admin?????(empty)
local?????0.078GB
tobytest??0.078GB
>?
MongoDB 中默認(rèn)的數(shù)據(jù)庫(kù)為 test,如果你沒(méi)有創(chuàng)建新的數(shù)據(jù)庫(kù),集合將存放在 test 數(shù)據(jù)庫(kù)中。
注意: 在 MongoDB 中,集合只有在內(nèi)容插入后才會(huì)創(chuàng)建! 就是說(shuō),創(chuàng)建集合(數(shù)據(jù)表)后要再插入一個(gè)文檔(記錄),集合才會(huì)真正創(chuàng)建。
MongoDB 創(chuàng)建集合
MongoDB 中使用 createCollection() 方法來(lái)創(chuàng)建集合。
語(yǔ)法格式:
db.createCollection(name,?options)
參數(shù)說(shuō)明:
name: 要?jiǎng)?chuàng)建的集合名稱 options: 可選參數(shù), 指定有關(guān)內(nèi)存大小及索引的選項(xiàng)
options 可以是如下參數(shù):
| 字段 | 類型 | 描述 |
|---|---|---|
| capped | 布爾 | (可選)如果為 true,則創(chuàng)建固定集合。固定集合是指有著固定大小的集合,當(dāng)達(dá)到最大值時(shí),它會(huì)自動(dòng)覆蓋最早的文檔。當(dāng)該值為 true 時(shí),必須指定 size 參數(shù)。 |
| autoIndexId | 布爾 | 3.2 之后不再支持該參數(shù)。(可選)如為 true,自動(dòng)在 _id 字段創(chuàng)建索引。默認(rèn)為 false。 |
| size | 數(shù)值 | (可選)為固定集合指定一個(gè)最大值,即字節(jié)數(shù)。如果 capped 為 true,也需要指定該字段。 |
| max | 數(shù)值 | (可選)指定固定集合中包含文檔的最大數(shù)量。 |
在插入文檔時(shí),MongoDB 首先檢查固定集合的 size 字段,然后檢查 max 字段。
實(shí)例
在 tobytest 數(shù)據(jù)庫(kù)中創(chuàng)建 runoob 集合:
>?use?tobytest
switched?to?db?tobytest
>?db.createCollection("tobycollection")
{?"ok"?:?1?}
>?
如果要查看已有集合,可以使用 show collections 或 show tables 命令:
>?show?tables
system.indexes
tobycollection
tobytest
>?
MongoDB 刪除集合
MongoDB 中使用 drop() 方法來(lái)刪除集合。
語(yǔ)法格式:
db.collection.drop()
參數(shù)說(shuō)明:
無(wú)
返回值
如果成功刪除選定集合,則 drop() 方法返回 true,否則返回 false。
實(shí)例
在數(shù)據(jù)庫(kù) tobytest中,我們可以先通過(guò) show collections 命令查看已存在的集合:
>?use?tobytest
switched?to?db?tobytest
>?show?collections
system.indexes
tobycollection
tobytest
>?
接著刪除集合 tobycollection:
>?db.tobycollection.drop()
true
>?
通過(guò) show collections 再次查看數(shù)據(jù)庫(kù) tobytest中的集合:
>?show?collections
system.indexes
tobytest
>?
從結(jié)果中可以看出 tobycollection集合已被刪除。
MongoDB 插入文檔
文檔的數(shù)據(jù)結(jié)構(gòu)和 JSON 基本一樣。
所有存儲(chǔ)在集合中的數(shù)據(jù)都是 BSON 格式。
BSON 是一種類似 JSON 的二進(jìn)制形式的存儲(chǔ)格式,是 Binary JSON 的簡(jiǎn)稱。
插入文檔
MongoDB 使用 insert() 或 save() 方法向集合中插入文檔,語(yǔ)法如下:
db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
save():如果 _id 主鍵存在則更新數(shù)據(jù),如果不存在就插入數(shù)據(jù)。該方法新版本中已廢棄,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 來(lái)代替。 insert(): 若插入的數(shù)據(jù)主鍵已經(jīng)存在,則會(huì)拋 org.springframework.dao.DuplicateKeyException 異常,提示主鍵重復(fù),不保存當(dāng)前數(shù)據(jù)。
實(shí)例
以下文檔可以存儲(chǔ)在 MongoDB 的 tobytest 數(shù)據(jù)庫(kù) 的 col 集合中:
>?db.col.insert({title:'Toby?MongoDB',
...?description:'this?is?MongoDB',
...?tags:['mongodb','database','NoSQL'],
...?likes:1
...?})
WriteResult({?"nInserted"?:?1?})
>?
以上實(shí)例中 col 是我們的集合名,如果該集合不在該數(shù)據(jù)庫(kù)中, MongoDB 會(huì)自動(dòng)創(chuàng)建該集合并插入文檔。
查看已插入文檔:
>?db.col.find()
{?"_id"?:?ObjectId("617970fc286e9ff2b1250d70"),?"title"?:?"Toby?MongoDB",?"description"?:?"this?is?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?1?}
>?
我們也可以將數(shù)據(jù)定義為一個(gè)變量,如下所示:
>?document=({title:'Toby?another?MongoDB',
...?description:'this?is?another?MongoDB',
...?tags:['mongodb','database','NoSQL'],
...?likes:2
...?})
執(zhí)行后顯示結(jié)果如下:
{
?"title"?:?"Toby?another?MongoDB",
?"description"?:?"this?is?another?MongoDB",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?2
}
執(zhí)行插入操作:
>?db.col.insert(document)
WriteResult({?"nInserted"?:?1?})
>?db.col.find()
{?"_id"?:?ObjectId("617970fc286e9ff2b1250d70"),?"title"?:?"Toby?MongoDB",?"description"?:?"this?is?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?1?}
{?"_id"?:?ObjectId("61797229286e9ff2b1250d71"),?"title"?:?"Toby?another?MongoDB",?"description"?:?"this?is?another?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?2?}
>?
MongoDB 更新文檔
MongoDB 使用 update() 和 save() 方法來(lái)更新集合中的文檔。接下來(lái)讓我們?cè)敿?xì)來(lái)看下兩個(gè)函數(shù)的應(yīng)用及其區(qū)別。
update() 方法
update() 方法用于更新已存在的文檔。語(yǔ)法格式如下:
db.collection.update(
???,
???,
???{
?????upsert:?,
?????multi:?,
?????writeConcern:?
???}
)
參數(shù)說(shuō)明:
query : update的查詢條件,類似sql update查詢內(nèi)where后面的。 update : update的對(duì)象和一些更新的操作符(如inc...)等,也可以理解為sql update查詢內(nèi)set后面的 upsert : 可選,這個(gè)參數(shù)的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認(rèn)是false,不插入。 multi : 可選,mongodb 默認(rèn)是false,只更新找到的第一條記錄,如果這個(gè)參數(shù)為true,就把按條件查出來(lái)多條記錄全部更新。 writeConcern :可選,拋出異常的級(jí)別。
實(shí)例
我們?cè)诩?col 中插入如下數(shù)據(jù):
>?db.col.insert({title:'Toby?MongoDB',
...?description:'this?is?MongoDB',
...?tags:['mongodb','database','NoSQL'],
...?likes:1
...?})
WriteResult({?"nInserted"?:?1?})
>?
接著我們通過(guò) update() 方法來(lái)更新標(biāo)題(title):
>?db.col.update({'title':'Toby?MongoDB'},{$set:{'title':'MongoDB'}})
WriteResult({?"nMatched"?:?1,?"nUpserted"?:?0,?"nModified"?:?1?})
>?db.col.find().pretty()
{
?"_id"?:?ObjectId("617970fc286e9ff2b1250d70"),
?"title"?:?"MongoDB",
?"description"?:?"this?is?MongoDB",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?1
}
{
?"_id"?:?ObjectId("61797229286e9ff2b1250d71"),
?"title"?:?"Toby?another?MongoDB",
?"description"?:?"this?is?another?MongoDB",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?2
}
>?
可以看到標(biāo)題(title)由原來(lái)的 "Toby MongoDB" 更新為了 "MongoDB"。
MongoDB 刪除文檔
MongoDB remove() 函數(shù)是用來(lái)移除集合中的數(shù)據(jù)。
MongoDB 數(shù)據(jù)更新可以使用 update() 函數(shù)。在執(zhí)行 remove() 函數(shù)前先執(zhí)行 find() 命令來(lái)判斷執(zhí)行的條件是否正確,這是一個(gè)比較好的習(xí)慣。
語(yǔ)法
remove() 方法的基本語(yǔ)法格式如下所示:
db.collection.remove(
???,
???
)
如果你的 MongoDB 是 2.6 版本以后的,語(yǔ)法格式如下:
db.collection.remove(
???,
???{
?????justOne:?,
?????writeConcern:?
???}
)
參數(shù)說(shuō)明:
query :(可選)刪除的文檔的條件。 justOne : (可選)如果設(shè)為 true 或 1,則只刪除一個(gè)文檔,如果不設(shè)置該參數(shù),或使用默認(rèn)值 false,則刪除所有匹配條件的文檔。 writeConcern :(可選)拋出異常的級(jí)別。
實(shí)例
以下文檔我們執(zhí)行兩次插入操作:
>?db.col.insert({title:'Toby?MongoDB',?description:'this?is?MongoDB',?tags:['mongodb','database','NoSQL'],?likes:1?})
WriteResult({?"nInserted"?:?1?})
>?db.col.insert({title:'Toby?MongoDB',?description:'this?is?MongoDB',?tags:['mongodb','database','NoSQL'],?likes:1?})
WriteResult({?"nInserted"?:?1?})
>?
使用 find() 函數(shù)查詢數(shù)據(jù):
>?db.col.find()
{?"_id"?:?ObjectId("617970fc286e9ff2b1250d70"),?"title"?:?"MongoDB",?"description"?:?"this?is?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?1?}
{?"_id"?:?ObjectId("61797229286e9ff2b1250d71"),?"title"?:?"Toby?another?MongoDB",?"description"?:?"this?is?another?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?2?}
{?"_id"?:?ObjectId("6179747d286e9ff2b1250d72"),?"title"?:?"Toby?MongoDB",?"description"?:?"this?is?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?1?}
{?"_id"?:?ObjectId("61797481286e9ff2b1250d73"),?"title"?:?"Toby?MongoDB",?"description"?:?"this?is?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?1?}
>?
接下來(lái)我們移除 title 為 'Toby MongoDB' 的文檔:
>?db.col.remove({'title':'Toby?MongoDB'})
WriteResult({?"nRemoved"?:?2?})?#?刪除了兩個(gè)
>?db.col.find()
{?"_id"?:?ObjectId("617970fc286e9ff2b1250d70"),?"title"?:?"MongoDB",?"description"?:?"this?is?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?1?}
{?"_id"?:?ObjectId("61797229286e9ff2b1250d71"),?"title"?:?"Toby?another?MongoDB",?"description"?:?"this?is?another?MongoDB",?"tags"?:?[?"mongodb",?"database",?"NoSQL"?],?"likes"?:?2?}
>?
如果你只想刪除第一條找到的記錄可以設(shè)置 justOne 為 1,如下所示:
>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
如果你想刪除所有數(shù)據(jù),可以使用以下方式(類似常規(guī) SQL 的 truncate 命令):
>?db.col.remove({})
WriteResult({?"nRemoved"?:?2?})
>?db.col.find()
>?
MongoDB 查詢文檔
MongoDB 查詢文檔使用 find() 方法。
find() 方法以非結(jié)構(gòu)化的方式來(lái)顯示所有文檔。
語(yǔ)法
MongoDB 查詢數(shù)據(jù)的語(yǔ)法格式如下:
db.collection.find(query,?projection)
query :可選,使用查詢操作符指定查詢條件 projection :可選,使用投影操作符指定返回的鍵。查詢時(shí)返回文檔中所有鍵值, 只需省略該參數(shù)即可(默認(rèn)省略)。
如果你需要以易讀的方式來(lái)讀取數(shù)據(jù),可以使用 pretty() 方法,語(yǔ)法格式如下:
>db.col.find().pretty()
pretty() 方法以格式化的方式來(lái)顯示所有文檔。
實(shí)例
以下實(shí)例我們查詢了集合 col 中的數(shù)據(jù):
>?db.col.insert({title:'Toby?MongoDB',?description:'this?is?MongoDB',by:'Toby',?tags:['mongodb','database','NoSQL'],?likes:100?})
WriteResult({?"nInserted"?:?1?})
>?db.col.find().pretty()
{
?"_id"?:?ObjectId("6179772f286e9ff2b1250d75"),
?"title"?:?"Toby?MongoDB",
?"description"?:?"this?is?MongoDB",
?"by"?:?"Toby",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?100
}
>?
除了 find() 方法之外,還有一個(gè) findOne() 方法,它只返回一個(gè)文檔。
MongoDB AND 條件
MongoDB 的 find() 方法可以傳入多個(gè)鍵(key),每個(gè)鍵(key)以逗號(hào)隔開(kāi),即常規(guī) SQL 的 AND 條件。
語(yǔ)法格式如下:
>db.col.find({key1:value1,?key2:value2}).pretty()
實(shí)例
以下實(shí)例通過(guò) by 和 title 鍵來(lái)查詢 Toby 中 Toby MongoDB 的數(shù)據(jù)
>?db.col.find({'by':'Toby','title':'Toby?MongoDB'}).prettydb.col.find({'by':'Toby','title':'Toby?MongoDB'}).pretty()
{
?"_id"?:?ObjectId("6179772f286e9ff2b1250d75"),
?"title"?:?"Toby?MongoDB",
?"description"?:?"this?is?MongoDB",
?"by"?:?"Toby",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?100
}
>?
以上實(shí)例中類似于 WHERE 語(yǔ)句:WHERE by='Toby' AND title='Toby MongoDB'
MongoDB OR 條件
MongoDB OR 條件語(yǔ)句使用了關(guān)鍵字 $or,語(yǔ)法格式如下:
>db.col.find(
???{
??????$or:?[
?????????{key1:?value1},?{key2:value2}
??????]
???}
).pretty()
實(shí)例
以下實(shí)例中,我們演示了查詢鍵 by 值為 Toby或鍵 title 值為 Toby MongoDB 的文檔。
>?db.col.find({$or:[{"by":"Toby"},{"title":"Toby?MongoDB"}]}).pretty()
{
?"_id"?:?ObjectId("6179772f286e9ff2b1250d75"),
?"title"?:?"Toby?MongoDB",
?"description"?:?"this?is?MongoDB",
?"by"?:?"Toby",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?100
}
>?
AND 和 OR 聯(lián)合使用
以下實(shí)例演示了 AND 和 OR 聯(lián)合使用,類似常規(guī) SQL 語(yǔ)句為:'where likes>50 AND (by = 'Toby' OR title = 'Toby MongoDB')'
>?db.col.find({"likes":{$gt:50},$or:[{"by":"Toby"},{"title":"Toby?MongoDB"}]}).pretty()
{
?"_id"?:?ObjectId("6179772f286e9ff2b1250d75"),
?"title"?:?"Toby?MongoDB",
?"description"?:?"this?is?MongoDB",
?"by"?:?"Toby",
?"tags"?:?[
??"mongodb",
??"database",
??"NoSQL"
?],
?"likes"?:?100
}
>?
MongoDB 排序
MongoDB sort() 方法
在 MongoDB 中使用 sort() 方法對(duì)數(shù)據(jù)進(jìn)行排序,sort() 方法可以通過(guò)參數(shù)指定排序的字段,并使用 1 和 -1 來(lái)指定排序的方式,其中 1 為升序排列,而 -1 是用于降序排列。
語(yǔ)法
sort()方法基本語(yǔ)法如下所示:
>db.COLLECTION_NAME.find().sort({KEY:1})
實(shí)例
col 集合中的數(shù)據(jù)如下:
>?db.col.find().pretty()
{
?"_id"?:?ObjectId("61797a56286e9ff2b1250d78"),
?"title"?:?"Toby?PHP",
?"description"?:?"this?is?PHP",
?"by"?:?"Toby",
?"tags"?:?[
??"PHP",
??"Language"
?],
?"likes"?:?100
}
{
?"_id"?:?ObjectId("61797a62286e9ff2b1250d79"),
?"title"?:?"Toby?JAVA",
?"description"?:?"this?is?JAVA",
?"by"?:?"Toby",
?"tags"?:?[
??"JAVA",
??"Language"
?],
?"likes"?:?50
}
{
?"_id"?:?ObjectId("61797a83286e9ff2b1250d7a"),
?"title"?:?"Toby?Python",
?"description"?:?"this?is?Python",
?"by"?:?"Toby",
?"tags"?:?[
??"Python",
??"Language"
?],
?"likes"?:?20
}
>?
以下實(shí)例演示了 col 集合中的數(shù)據(jù)按字段 likes 的降序排列:
>?db.col.find({},{'title':1,_id:0}).sort({"likes":-1})
{?"title"?:?"Toby?PHP"?}
{?"title"?:?"Toby?JAVA"?}
{?"title"?:?"Toby?Python"?}
>?
Python MongoDB
PyMongo
Python 要連接 MongoDB 需要 MongoDB 驅(qū)動(dòng),這里我們使用 PyMongo 驅(qū)動(dòng)來(lái)連接。
pip 安裝
pip 是一個(gè)通用的 Python 包管理工具,提供了對(duì) Python 包的查找、下載、安裝、卸載的功能。
安裝 pymongo:
$?python3?-m?pip?install?pymongo
測(cè)試 PyMongo
接下來(lái)我們可以創(chuàng)建一個(gè)測(cè)試文件 demo_test_mongodb.py,代碼如下:
import?pymongo
執(zhí)行以上代碼文件,如果沒(méi)有出現(xiàn)錯(cuò)誤,表示安裝成功。
創(chuàng)建數(shù)據(jù)庫(kù)
創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)
創(chuàng)建數(shù)據(jù)庫(kù)需要使用 MongoClient 對(duì)象,并且指定連接的 URL 地址和要?jiǎng)?chuàng)建的數(shù)據(jù)庫(kù)名。
如下實(shí)例中,我們創(chuàng)建的數(shù)據(jù)庫(kù) pydb:
實(shí)例
import?pymongo
myclient=pymongo.MongoClient("mongodb://localhost:27017/")
mydb=myclient["pydb"]
注意: 在 MongoDB 中,數(shù)據(jù)庫(kù)只有在內(nèi)容插入后才會(huì)創(chuàng)建! 就是說(shuō),數(shù)據(jù)庫(kù)創(chuàng)建后要?jiǎng)?chuàng)建集合(數(shù)據(jù)表)并插入一個(gè)文檔(記錄),數(shù)據(jù)庫(kù)才會(huì)真正創(chuàng)建。
判斷數(shù)據(jù)庫(kù)是否已存在
我們可以讀取 MongoDB 中的所有數(shù)據(jù)庫(kù),并判斷指定的數(shù)據(jù)庫(kù)是否存在:
實(shí)例
import?pymongo
myclient=pymongo.MongoClient("mongodb://localhost:27017/")
mydb=myclient["pydb"]
dblist?=?myclient.list_database_names()
#?dblist?=?myclient.database_names()?
if?"pydb"?in?dblist:
??print("數(shù)據(jù)庫(kù)已存在!")
else:
??print('數(shù)據(jù)庫(kù)不存在')
**注意:**database_names 在最新版本的 Python 中已廢棄,Python3.7+ 之后的版本改為了 list_database_names()。

創(chuàng)建集合
MongoDB 中的集合類似 SQL 的表。
創(chuàng)建一個(gè)集合
MongoDB 使用數(shù)據(jù)庫(kù)對(duì)象來(lái)創(chuàng)建集合,實(shí)例如下:
實(shí)例
import?pymongo
myclient=pymongo.MongoClient("mongodb://localhost:27017/")
mydb=myclient["pydb"]
mycol=myclient["col_set"]
注意: 在 MongoDB 中,集合只有在內(nèi)容插入后才會(huì)創(chuàng)建! 就是說(shuō),創(chuàng)建集合(數(shù)據(jù)表)后要再插入一個(gè)文檔(記錄),集合才會(huì)真正創(chuàng)建。
判斷集合是否已存在
我們可以讀取 MongoDB 數(shù)據(jù)庫(kù)中的所有集合,并判斷指定的集合是否存在:
實(shí)例
import?pymongo
myclient=pymongo.MongoClient("mongodb://localhost:27017/")
mydb=myclient["pydb"]
mycol=myclient["col_set"]
collist?=?mydb.?list_collection_names()
if?"col_set"?in?collist:???#?判斷?sites?集合是否存在
??print("集合已存在!")
else:
??print('集合不存在')

Python Mongodb 插入文檔
MongoDB 中的一個(gè)文檔類似 SQL 表中的一條記錄。
插入集合
集合中插入文檔使用 insert_one() 方法,該方法的第一參數(shù)是字典 name => value 對(duì)。
以下實(shí)例向 col_set 集合中插入文檔:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
?
mydict?=?{?"name":?"Toby",?"age":?"23",?"url":?"https://juejin.cn/user/3403743731649863"?}
?
x?=?mycol.insert_one(mydict)?
print(x)

在命令行看一下是否插入成功
>?use?pydb
switched?to?db?pydb
>?db.col_set.find()
{?"_id"?:?ObjectId("617ce42cbc6011eaf1529012"),?"name"?:?"Toby",?"url"?:?"https://juejin.cn/user/3403743731649863",?"age"?:?"23"?}
>?
插入多個(gè)文檔
集合中插入多個(gè)文檔使用 insert_many() 方法,該方法的第一參數(shù)是字典列表。
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
?
mylist?=?[
??{?"name":?"Tom",?"age":?"100",?"url":?"https://juejin.cn/user/3403743731649863"?},
??{?"name":?"Mary",?"age":?"101",?"url":?"https://juejin.cn/user/3403743731649863"?},
??{?"name":?"Timi",?"age":?"10",?"url":?"https://juejin.cn/user/3403743731649863"?},
]
?
x?=?mycol.insert_many(mylist)
?
#?輸出插入的所有文檔對(duì)應(yīng)的?_id?值
print(x.inserted_ids)

在命令行看一下是否插入成功
>?use?pydb
switched?to?db?pydb
>?db.col_set.find()
{?"_id"?:?ObjectId("617ce42cbc6011eaf1529012"),?"name"?:?"Toby",?"url"?:?"https://juejin.cn/user/3403743731649863",?"age"?:?"23"?}
{?"_id"?:?ObjectId("617ce591826d13d898f97890"),?"name"?:?"Tom",?"url"?:?"https://juejin.cn/user/3403743731649863",?"age"?:?"100"?}
{?"_id"?:?ObjectId("617ce591826d13d898f97891"),?"name"?:?"Mary",?"url"?:?"https://juejin.cn/user/3403743731649863",?"age"?:?"101"?}
{?"_id"?:?ObjectId("617ce591826d13d898f97892"),?"name"?:?"Timi",?"url"?:?"https://juejin.cn/user/3403743731649863",?"age"?:?"10"?}
>?
Python Mongodb 查詢文檔
MongoDB 中使用了 find 和 find_one 方法來(lái)查詢集合中的數(shù)據(jù),它類似于 SQL 中的 SELECT 語(yǔ)句。
查詢一條數(shù)據(jù)
我們可以使用 find_one() 方法來(lái)查詢集合中的一條數(shù)據(jù)。
查詢 col_set 文檔中的第一條數(shù)據(jù):
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
?
x?=?mycol.find_one()
?
print(x)

查詢集合中所有數(shù)據(jù)
find() 方法可以查詢集合中的所有數(shù)據(jù),類似 SQL 中的 SELECT * 操作。
以下實(shí)例查找 col_set 集合中的所有數(shù)據(jù):
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
for?x?in?mycol.find():
??print(x)

查詢指定字段的數(shù)據(jù)
我們可以使用 find() 方法來(lái)查詢指定字段的數(shù)據(jù),將要返回的字段對(duì)應(yīng)值設(shè)置為 1。
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
for?x?in?mycol.find({},{?"_id":?0,?"name":?1,?"age":?1?}):
??print(x)

根據(jù)指定條件查詢
我們可以在 find() 中設(shè)置參數(shù)來(lái)過(guò)濾數(shù)據(jù)。
以下實(shí)例查找 name 字段為 "Toby" 的數(shù)據(jù):
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
myquery?=?{?"name":?"Toby"?}
?
mydoc?=?mycol.find(myquery)
?
for?x?in?mydoc:
??print(x)

返回指定條數(shù)記錄
如果我們要對(duì)查詢結(jié)果設(shè)置指定條數(shù)的記錄可以使用 limit() 方法,該方法只接受一個(gè)數(shù)字參數(shù)。
以下實(shí)例返回 3 條文檔記錄:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
myresult?=?mycol.find().limit(3)
?
#?輸出結(jié)果
for?x?in?myresult:
??print(x)

Python Mongodb 修改文檔
我們可以在 MongoDB 中使用 update_one() 方法修改文檔中的記錄。該方法第一個(gè)參數(shù)為查詢的條件,第二個(gè)參數(shù)為要修改的字段。
如果查找到的匹配數(shù)據(jù)多于一條,則只會(huì)修改第一條。
以下實(shí)例將 age字段的值 23改為 12345:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
myquery?=?{?"age":?"23"?}
newvalues?=?{?"$set":?{?"age":?"12345"?}?}
?
mycol.update_one(myquery,?newvalues)
?
#?輸出修改后的??"sites"??集合
for?x?in?mycol.find():
??print(x)

排序
sort() 方法可以指定升序或降序排序。
sort() 方法第一個(gè)參數(shù)為要排序的字段,第二個(gè)字段指定排序規(guī)則,1 為升序,-1 為降序,默認(rèn)為升序。
對(duì)字段 age 按升序排序:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
mydoc?=?mycol.find().sort("age")
for?x?in?mydoc:
??print(x)

對(duì)字段 age按降序排序:
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
mydoc?=?mycol.find().sort("alexa",?-1)
?
for?x?in?mydoc:
??print(x)

Python Mongodb 刪除數(shù)據(jù)
我們可以使用 delete_one() 方法來(lái)刪除一個(gè)文檔,該方法第一個(gè)參數(shù)為查詢對(duì)象,指定要?jiǎng)h除哪些數(shù)據(jù)。
以下實(shí)例刪除 name 字段值為 "Timi" 的文檔:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
myquery?=?{?"name":?"Timi"?}
?
mycol.delete_one(myquery)
?
#?刪除后輸出
for?x?in?mycol.find():
??print(x)

刪除集合中的所有文檔
delete_many() 方法如果傳入的是一個(gè)空的查詢對(duì)象,則會(huì)刪除集合中的所有文檔:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
x?=?mycol.delete_many({})
?
print(x.deleted_count,?"個(gè)文檔已刪除")

刪除集合
我們可以使用 drop() 方法來(lái)刪除一個(gè)集合。
以下實(shí)例刪除了 col_set集合:
實(shí)例
import?pymongo
?
myclient?=?pymongo.MongoClient("mongodb://localhost:27017/")
mydb?=?myclient["pydb"]
mycol?=?mydb["col_set"]
??
mycol.drop()
我們?cè)诮K端查看一下
>?use?pydb
switched?to?db?pydb
>?show?tables
system.indexes
>?
總結(jié)
本文主要介紹了MongoDB數(shù)據(jù)庫(kù)的相關(guān)概念及基本操作,為了更好的了解MongoDB在新聞推薦系統(tǒng)中的應(yīng)用,需要了解數(shù)據(jù)庫(kù)的相關(guān)概念并熟練使用python操作MongoDB。
參考資料
https://www.runoob.com/python3/python-mongodb.html
https://www.runoob.com/mongodb/mongodb-tutorial.html
--end-- 掃碼即可加我微信
學(xué)習(xí)交流
老表朋友圈經(jīng)常有贈(zèng)書(shū)/紅包福利活動(dòng)
