mongo数据库CRUD
#準備
從官網下載合適的安裝包。這里以win10為例,一路next即可完成安裝。安裝完成后,進入這個目錄:
C:\Program Files\MongoDB\Server\4.0\bin\在當前目錄打開PowerShell窗口,先啟動服務端:
.\mongod.exe服務端默認在本地的27017端口運行。
啟動客戶端:
.\mongo.exe將默認連接本地27017端口的服務端,并啟動mongo shell交互式命令行窗口。
如果想指定端口或者連接遠程的服務,可以在啟動時指定其他參數,比如:
.\mongo.exe --host www.example.com --port 28015顯示當前使用的數據庫:
db # 默認數據庫是test切換數據庫:
use <database>你也可以切換到一個不存在的數據庫。因為當你往其中插入數據時,mongo將自動創建這個數據庫(或者集合),比如:
> use first switched to db first > db.test_coll.insertOne({x:1}) {"acknowledged" : true,"insertedId" : ObjectId("5c52cdf38410c398987c5c0e") }上述的insertOne()操作將同時創建數據庫first和集合test_coll。
PyMongo
連接和指定數據庫
PyMongo是mongo的python驅動,安裝好之后我們連接MongoDB
方式一:指定主機和端口
import pymongo client = pymongo.MongoClient(host='localhost', port=27017)方式二:mongodb連接字符串
client = pymongo.MongoClient('mongodb://localhost:27017/') db = db.test # 默認數據庫是test插入數據
數據庫
默認數據庫是test,我們也可以指定其他數據庫,比如school
client = pymongo.MongoClient('mongodb://localhost:27017/') db = client.school # 或者 db = client['school']注意,可以直接連接一個不存在的數據庫。mongo會在需要時(比如插入數據),創建這個數據庫。
集合
mongo中的集合(collection),類似于SQL中的表(table)。指定集合的操作,與指定數據庫的方式類似:
collection = db.teacher # 或者 collection = db['teacher']注意,可以指定一個不存在的集合。mongo會在需要時(比如插入數據),創建這個集合。
文檔
MongoDB將數據存儲為BSON文檔(BSON是JSON文檔的二進制表示,但是包含更多的數據類型)。文檔由字段(field)和值(value)組成,具有如下結構:
{field1: value1,field2: value2,field3: value3,...fieldN: valueN }字段名是字符串,具有如下約束條件:
- _id是保留字段,用作主鍵,必須保證唯一且不可以變(因此不能是數組)
- 字段名不可包含null字符
- 不要以$或.開頭
- 字段名不可重復
在PyMongo中,使用python的字典表示文檔,例如下面字典可以用來表示一篇博文:
>>> import datetime >>> post = {"author": "Mike", ... "text": "My first blog post!", ... "tags": ["mongodb", "python", "pymongo"], ... "date": datetime.datetime.utcnow()}值得注意的是,文檔可以包含python中的原生類型(比如datetime.datetime實例),PyMongo會將其自動轉化為合適的BSON類型。
點
MongoDB使用.點來訪問數組或嵌套文檔中的元素:
{...contribs: [ "Turing machine", "Turing test", "Turingery" ],... }如果要訪問contribs字段的第三個元素,使用contribs.2
{...name: { first: "Alan", last: "Turing" },contact: { phone: { type: "cell", number: "111-222-3333" } },... }如果要訪問name字段的last字段,使用name.last
文檔的限制
- BSON文檔的最大大小是16MB
- 字段的順序:MongoDB保持寫操作時的字段順序,除了以下情況:
- _id字段總是文檔的第一個字段
- 重新命名字段等更新操作可能影響字段排序
- _id字段:
- 如果插入文檔沒有指定_id字段,MongoDB會自動創建ObjectId對象作為該字段的值
- 創建集合(collection)時,MongoDB默認為該字段創建唯一索引
- 該字段的值通常是:
- ObjectId
- 自增數字
- 代碼生成的UUID
插入數據
MongoDB的所有寫操作,在當個文檔上是原子性的。插入文檔時,如果集合不存在,MongoDB會自動創建。
db.collection.insert()
下面我們往teacher這個集合中插入一條數據
# 數據用字典結構 teacher = {'name': 'Sven','gender': 'male','major': 'Math' }# 插入成功后,返回該條數據的 _id res = db.teacher.insert(teacher) # 5c53c429bddaf0ac186d935b插入多條數據
teacher1 = {'name': 'Sylvia','gender': 'female','major': 'Deutsch' }teacher2 = {'name': 'Lolle','gender': 'female','major': 'Geschichte' }res = db.teacher.insert([teacher1, teacher2]) # 返回_id的列表 # [ObjectId('5c53c628bddaf0b2bc028a73'), ObjectId('5c53c628bddaf0b2bc028a74')]以上我們插入單條和多條都用insert方法,更推薦的方式是使用insert_one()和insert_many()
db.collection.insert_one()
插入單條數據
res = db.inventory.insert_one({"item": "canvas","qty": 100,"tags": ["cotton"],"size": {"h": 28, "w": 35.5, "uom": "cm"}})print(res) # <pymongo.results.InsertOneResult object at 0x0332EF58> print(res.inserted_id) # 5c53c7a8bddaf0208cd858f5db.collection.insert_many()
插入多條數據
res = db.inventory.insert_many([{"item": "journal","qty": 25,"tags": ["blank", "red"],"size": {"h": 14, "w": 21, "uom": "cm"}},{"item": "mat","qty": 85,"tags": ["gray"],"size": {"h": 27.9, "w": 35.5, "uom": "cm"}},{"item": "mousepad","qty": 25,"tags": ["gel", "blue"],"size": {"h": 19, "w": 22.85, "uom": "cm"}}])print(res) # <pymongo.results.InsertManyResult object at 0x031C3F30> print(res.inserted_ids) # [ObjectId('5c53e48bbddaf04c44880d70'), ObjectId('5c53e48bbddaf04c44880d71'), ObjectId('5c53e48bbddaf04c44880d72')]插入數據時,如果指定_id的值,那么該值不能和集合中已有文檔的_id重復。
查詢數據
查詢使用db.collection.find()方法。
首先,準備一些原始數據
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test1db.inventory.insert_many([{"item": "journal","qty": 25,"size": {"h": 14, "w": 21, "uom": "cm"},"status": "A"},{"item": "notebook","qty": 50,"size": {"h": 8.5, "w": 11, "uom": "in"},"status": "A"},{"item": "paper","qty": 100,"size": {"h": 8.5, "w": 11, "uom": "in"},"status": "D"},{"item": "planner","qty": 75, "size": {"h": 22.85, "w": 30, "uom": "cm"},"status": "D"},{"item": "postcard","qty": 45,"size": {"h": 10, "w": 15.25, "uom": "cm"},"status": "A"}])查詢集合中的所有文檔:find()
傳入一個空文檔作為find的查詢條件即可
cursor = db.inventory.find({})以上操作相當于SQL中的:
SELECT * FROM inventoryfind方法返回一個Cursor實例,遍歷它即可訪問所有文檔:
docs = [doc for doc in cursor] """ [{'status': 'A', 'item': 'journal', ...}, ...] """查詢單個文檔:find_one()
find_one()方法返回滿足查詢條件的一個文檔,或者返回None(如果沒有匹配的結果)。適用于:
- 你知道有且只有一個匹配的文檔,比如通過ObjectId進行查詢
- 你只需要第一個匹配的文檔
根據ObjectID對象查詢
注意,ObjectId對象和它的字符串表現是完全不同的,后者不可直接用于查詢
import pymongo import datetimeclient = pymongo.MongoClient(host='localhost',port=27017,retryWrites=True ) db = client.test8blog = {"author": "Ayhan","text": "My first blog post!","tags": ["mongodb", "python", "pymongo"],"date": datetime.datetime.utcnow()}post_id = db.posts.insert_one(blog).inserted_id # 返回ObjectId對象 print(post_id) # 5c948354bddaf02674a54faares1 = db.posts.find_one({'_id': post_id}) # 通過ObjectId對象查詢 print(res1) """ {'_id': ObjectId('5c948354bddaf02674a54faa'),'author': 'Ayhan','text': 'My first blog post!','tags': ['mongodb', 'python', 'pymongo'],'date': datetime.datetime(2019, 3, 22, 6, 40, 20, 164000) } """res2 = db.posts.find_one({'_id': str(post_id)}) # 通過ObjectId對象的字符串表現進行查詢 print(res2) # None如果想通過ObjectId的字符串進行查詢,需要將字符串轉為對象:
from bson.objectid import ObjectIdobject_id_str = '5c948354bddaf02674a54faa' db.posts.find_one({'_id': ObjectId(object_id_str)})指定相等條件
如果要指定相等條件,可以給find方法傳入文檔查詢條件:
{ <field1>: <value1>, ... }比如,下面的示例從inventory集合中查詢所有符合status等于D的文檔:
cursor = db.inventory.find({'status': 'D'})上述操作相當于SQL中的
SELECT * FROM inventory WHERE status = "D"使用查詢運算符
文檔查詢條件:
{ <field1>: { <operator1>: <value1> }, ... }下面的示例從inventory集合中查詢所有status等于A或D的文檔:
cursor = db.inventory.find({'status': {'$in': ['A', 'D']}})以上查詢相當于SQL中的:
SELECT * FROM inventory WHERE status in ("A", "D")查詢運算符一覽,可查看官方文檔:https://docs.mongodb.com/manual/reference/operator/query/#projection-operators
AND查詢
復合查詢可以指定多個字段。下面的示例從inventory集合中查詢所有status等于A,并且qty小于30的文檔:
cursor = db.inventory.find({'status': 'A', 'qty': {'$lt': 30}})以上操作相當于SQL中的:
SELECT * FROM inventory WHERE status = "A" AND qty < 30OR查詢
使用$or運算符,可以進行邏輯或查詢:
cursor = db.inventory.find({'$or': [{'status': 'A'}, {'qty': {'$lt': 30}}]} )以上操作相當于SQL中的:
SELECT * FROM inventory WHERE status = "A" OR qty < 3AND 和 OR 查詢
cursor = db.inventory.find({'status': 'A','$or': [{'qty': {'$lt': 30}}, {'item': {'$regex': '^p'}}] })以上操作相當于SQL中的:
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")嵌套查詢
適用于文檔中嵌套文檔的查詢。下面先填充數據:
import pymongo from bson.son import SONclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test2db.inventory.insert_many([{"item": "journal","qty": 25,"size": SON([("h", 14), ("w", 21), ("uom", "cm")]),"status": "A"},{"item": "notebook","qty": 50,"size": SON([("h", 8.5), ("w", 11), ("uom", "in")]),"status": "A"},{"item": "paper","qty": 100,"size": SON([("h", 8.5), ("w", 11), ("uom", "in")]),"status": "D"},{"item": "planner","qty": 75,"size": SON([("h", 22.85), ("w", 30), ("uom", "cm")]),"status": "D"},{"item": "postcard","qty": 45,"size": SON([("h", 10), ("w", 15.25), ("uom", "cm")]),"status": "A"}])注意,子文檔鍵的順序在這些示例中很重要,因此這里的子文檔使用bson.son.SON的實例,而不是使用python的字典形式。
插入后,數據結構如下:
[{ // 文檔"_id" : ObjectId("5c540556bddaf0b00803d342"),"status" : "A","item" : "journal","size" : { // 子文檔(嵌套文檔)"h" : 14,"w" : 21,"uom" : "cm"},"qty" : 25} ]根據子文檔進行查詢
如果某個字段是一個子文檔,要為該字段指定相等條件時,使用如下文檔查詢條件:{ <field>: <value> },其中<value>是作為匹配條件的子文檔。
下面的示例從inventory集合中查詢size字段等于子文檔{ h: 14, w:21, uom: "cm" }的文檔
cursor = db.inventory.find({'size': SON([("h", 14), ("w", 21), ("uom", "cm")])} ) """ [{u 'status': u 'A',u 'item': u 'journal',u '_id': ObjectId('5c540556bddaf0b00803d342'),u 'qty': 25,u 'size': {u 'h': 14,u 'uom': u 'cm',u 'w': 21} }] """注意:
根據子文檔進行查詢時,子文檔必須完全匹配,包括字段的順序。也就也是說,下面的查詢無法匹配任何結果:
cursor = db.inventory.find({"size": SON([("w", 21), ("h", 14), ("uom", "cm")])} ) # []根據嵌套字段進行查詢
通過子文檔的字段進行查詢,需要使用.操作:field.nestedField
# 查詢 size.uom 等于 in 的文檔 cursor = db.inventory.find({'size.uom': 'in'} ) """ [{u 'status': u 'A',u 'item': u 'notebook',u '_id': ObjectId('5c540556bddaf0b00803d343'),u 'qty': 50,u 'size': {u 'h': 8.5,u 'uom': u 'in',u 'w': 11} }, {u 'status': u 'D',u 'item': u 'paper',u '_id': ObjectId('5c540556bddaf0b00803d344'),u 'qty': 100,u 'size': {u 'h': 8.5,u 'uom': u 'in',u 'w': 11} }] """ # 查詢 size.h 小于 10 的文檔 cursor = db.inventory.find({'size.h': {'$lt': 10}} ) """ [{u 'status': u 'A',u 'item': u 'notebook',u '_id': ObjectId('5c540556bddaf0b00803d343'),u 'qty': 50,u 'size': {u 'h': 8.5,u 'uom': u 'in',u 'w': 11} }, {u 'status': u 'D',u 'item': u 'paper',u '_id': ObjectId('5c540556bddaf0b00803d344'),u 'qty': 100,u 'size': {u 'h': 8.5,u 'uom': u 'in',u 'w': 11} }] """ # 查詢 size.h 小于 15,size.uom 等于 in, 并且status 等于D的文檔 cursor = db.inventory.find({'size.h': {'$lt': 15}, 'size.uom': 'in', 'status': 'D'} ) """ [{u 'status': u 'D',u 'item': u 'paper',u '_id': ObjectId('5c540556bddaf0b00803d344'),u 'qty': 100,u 'size': {u 'h': 8.5,u 'uom': u 'in',u 'w': 11} }] """數組查詢
首先準備數據:
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test3db.inventory.insert_many([{"item": "journal","qty": 25,"tags": ["blank", "red"],"dim_cm": [14, 21]},{"item": "notebook","qty": 50,"tags": ["red", "blank"],"dim_cm": [14, 21]},{"item": "paper","qty": 100,"tags": ["red", "blank", "plain"],"dim_cm": [14, 21]},{"item": "planner","qty": 75,"tags": ["blank", "red"],"dim_cm": [22.85, 30]},{"item": "postcard","qty": 45,"tags": ["blue"],"dim_cm": [10, 15.25]},{"item": "mac","qty": 12,"tags": ["silver", "golden"],"dim_cm": [25, 34]} ])查詢整個數組
根據數組指定相等條件時,使用文檔查詢條件:{ <field>: <value> },其中<value>就是要進行匹配的數組本身,包括其中元素的順序。
# 查詢tags字段的值等于['red', 'blank']的文檔 cursor = db.inventory.find({'tags': ['red', 'blank']} ) """ [{u 'item': u 'notebook',u '_id': ObjectId('5c54138fbddaf0a1e075f0ff'),u 'qty': 50,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank'] }] """當然,如果你希望查詢數組中包含red和blank元素(不關心元素順序,或者是否有多余元素)的所有文檔,可以使用$all操作符:
cursor = db.inventory.find({'tags': {'$all': ['red', 'blank']}} ) """ [{u 'item': u 'journal',u '_id': ObjectId('5c54138fbddaf0a1e075f0fe'),u 'qty': 25,u 'dim_cm': [14, 21],u 'tags': [u 'blank', u 'red'] }, {u 'item': u 'notebook',u '_id': ObjectId('5c54138fbddaf0a1e075f0ff'),u 'qty': 50,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank'] }, {u 'item': u 'paper',u '_id': ObjectId('5c54138fbddaf0a1e075f100'),u 'qty': 100,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank', u 'plain'] }, {u 'item': u 'planner',u '_id': ObjectId('5c54138fbddaf0a1e075f101'),u 'qty': 75,u 'dim_cm': [22.85, 30],u 'tags': [u 'blank', u 'red'] }] """查詢數組中的某個元素(指定單個查詢條件)
查詢數組中包含某個元素的文檔時,使用{ <field>: <value> },其中<value>是數組中的元素
# 查詢tags中包含red的文檔 cursor = db.inventory.find({'tags': 'red'} ) """ [{u 'item': u 'journal',u '_id': ObjectId('5c54138fbddaf0a1e075f0fe'),u 'qty': 25,u 'dim_cm': [14, 21],u 'tags': [u 'blank', u 'red'] }, {u 'item': u 'notebook',u '_id': ObjectId('5c54138fbddaf0a1e075f0ff'),u 'qty': 50,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank'] }, {u 'item': u 'paper',u '_id': ObjectId('5c54138fbddaf0a1e075f100'),u 'qty': 100,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank', u 'plain'] }, {u 'item': u 'planner',u '_id': ObjectId('5c54138fbddaf0a1e075f101'),u 'qty': 75,u 'dim_cm': [22.85, 30],u 'tags': [u 'blank', u 'red'] }] """如果要給數組元素指定多個條件,可以在查詢條件中使用查詢運算符:{<array filed>: {<operator1>: <value1>, ...},具體如下個部分
為數組內的元素指定多個查詢條件
當為數組內的元素指定多個條件時,你可以指定要么單個元素滿足這些條件,或者數組內元素的任意組合滿足這些條件。
# 查詢dim_cm數組中元素的組合滿足查詢條件: # 一個元素大于15,另一個元素小于20,或者一個元素滿足兩種條件的的文檔 cursor = db.inventory.find({'dim_cm': {'$gt': 15, '$lt': 20}} ) """ [{u 'item': u 'journal',u '_id': ObjectId('5c54138fbddaf0a1e075f0fe'),u 'qty': 25,u 'dim_cm': [14, 21],u 'tags': [u 'blank', u 'red'] }, {u 'item': u 'notebook',u '_id': ObjectId('5c54138fbddaf0a1e075f0ff'),u 'qty': 50,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank'] }, {u 'item': u 'paper',u '_id': ObjectId('5c54138fbddaf0a1e075f100'),u 'qty': 100,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank', u 'plain'] }, {u 'item': u 'postcard',u '_id': ObjectId('5c54138fbddaf0a1e075f102'),u 'qty': 45,u 'dim_cm': [10, 15.25],u 'tags': [u 'blue'] }] 注意:"dim_cm": [25, 34]的元素并不會被過濾出來。 """一個數組元素同時滿足多個條件
使用$elemMatch運算符,指定多個條件,只要有1個元素同時滿足這些條件即可。
# 查詢dim_cm數組中,至少有一個大于15且小于20的元素的文檔 cursor = db.inventory.find({'dim_cm': {'$elemMatch': {'$gt': 15, '$lt': 20}}} ) """ [{u 'item': u 'postcard',u '_id': ObjectId('5c8ba39bbddaf00ea0365693'),u 'qty': 45,u 'dim_cm': [10, 15.25],u 'tags': [u 'blue'] }] 15.25 滿足既大于15,又小于20的條件 """元素的組合滿足復合查詢條件
# 查詢dim_cm數組中元素的組合滿足查詢條件: # 存在某些元素大于15,且某些元素小于20,或者一個元素滿足兩種條件的的文檔 # (若instock下的所有元素的組合都不能滿足以上條件,則無法被過濾出來) # 注意:"dim_cm": [25, 34]的元素并不會被過濾出來。 cursor = db.inventory.find({'dim_cm': {'$gt': 15, '$lt': 20}} ) """ [{u 'item': u 'journal',u '_id': ObjectId('5c54138fbddaf0a1e075f0fe'),u 'qty': 25,u 'dim_cm': [14, 21],u 'tags': [u 'blank', u 'red'] }, {u 'item': u 'notebook',u '_id': ObjectId('5c54138fbddaf0a1e075f0ff'),u 'qty': 50,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank'] }, {u 'item': u 'paper',u '_id': ObjectId('5c54138fbddaf0a1e075f100'),u 'qty': 100,u 'dim_cm': [14, 21],u 'tags': [u 'red', u 'blank', u 'plain'] }, {u 'item': u 'postcard',u '_id': ObjectId('5c54138fbddaf0a1e075f102'),u 'qty': 45,u 'dim_cm': [10, 15.25],u 'tags': [u 'blue'] }] """通過數組的索引查詢元素
使用.點,根據數組中指定索引的元素進行查詢。索引從0開始。
# 根據dim_cm數組的第一個元素,滿足大于20,且小于25進行查詢 cursor = db.inventory.find({'dim_cm.0': {'$gt': 20, '$lt': 25}} ) """ [{u 'item': u 'planner',u '_id': ObjectId('5c8ba39bbddaf00ea0365692'),u 'qty': 75,u 'dim_cm': [22.85, 30],u 'tags': [u 'blank', u 'red'] }] """包含子文檔的數組
準備數據:
import pymongo from bson.son import SONclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test4db.inventory.insert_many([{"item": "journal","instock": [SON([("warehouse", "A"), ("qty", 5)]),SON([("warehouse", "C"), ("qty", 15)])]},{"item": "notebook","instock": [SON([("warehouse", "C"), ("qty", 5)])]},{"item": "paper","instock": [SON([("warehouse", "A"), ("qty", 60)]),SON([("warehouse", "B"), ("qty", 15)])]},{"item": "planner","instock": [SON([("warehouse", "A"), ("qty", 40)]),SON([("warehouse", "B"), ("qty", 5)])]},{"item": "postcard","instock": [SON([("warehouse", "B"), ("qty", 15)]),SON([("warehouse", "C"), ("qty", 35)])]}])根據子文檔進行匹配
# instock數組的某個元素能匹配指定的文檔 cursor = db.inventory.find({'instock': SON([('warehouse', 'A'), ('qty', 5)]) })""" [{u 'item': u 'journal',u '_id': ObjectId('5c8c5f4abddaf049404c5e89'),u 'instock': [{ // 該元素能夠匹配指定的文檔條件u 'warehouse': u 'A',u 'qty': 5}, {u 'warehouse': u 'C',u 'qty': 15}] }] """根據文檔進行匹配是嚴格匹配,包括文檔的順序,因此如下查詢無法匹配任何結果:
cursor = db.inventory.find({'instock': SON([('qty', 5), ('warehouse', 'A')]) })對子文檔的 某個字段指定單個查詢條件
對所有子文檔內的某個字段指定一個查詢條件
# 查詢instock數組內至少包含一個子文檔,其滿足qty字段小于等于10的所有文檔 cursor = db.inventory.find({'instock.qty': {'$lte': 10} }) """ [{u 'item': u 'journal',u '_id': ObjectId('5c8c5f4abddaf049404c5e89'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 5}, {u 'warehouse': u 'C',u 'qty': 15}] }, {u 'item': u 'notebook',u '_id': ObjectId('5c8c5f4abddaf049404c5e8a'),u 'instock': [{u 'warehouse': u 'C',u 'qty': 5}] }, {u 'item': u 'planner',u '_id': ObjectId('5c8c5f4abddaf049404c5e8c'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 40}, {u 'warehouse': u 'B',u 'qty': 5}] }] """使用數組索引來指定子文檔的某個字段進行查詢
# 查詢instock數組的第一個子文檔的qty字段滿足大于20的所有文檔 cursor = db.inventory.find({'instock.0.qty': {'$gt': 20} }) """ [{u 'item': u 'paper',u '_id': ObjectId('5c8c5f4abddaf049404c5e8b'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 60}, {u 'warehouse': u 'B',u 'qty': 15}] }, {u 'item': u 'planner',u '_id': ObjectId('5c8c5f4abddaf049404c5e8c'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 40}, {u 'warehouse': u 'B',u 'qty': 5}] }] """對子文檔指定多個字段查詢條件
當對子文檔指定多個字段查詢條件時,你可以指定要么單個子文檔滿足這些條件,或者任意子文檔的組合滿足條件(類似上面的數組內元素指定多個條件)
單個子文檔滿足多個字段的查詢條件
使用$elemMatch運算符對包含子文檔的數組指定多個條件,至少有一個子文檔能滿足這些條件即可
# 查詢instock數組至少包含一個子文檔同時滿足qty等于5,warehouse等于4的所有文檔 cursor = db.inventory.find({'instock': {'$elemMatch': {'qty': 5, 'warehouse': 'A'}} })""" [{u 'item': u 'journal',u '_id': ObjectId('5c8c5f4abddaf049404c5e89'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 5}, {u 'warehouse': u 'C',u 'qty': 15}] }] """ # 查詢instock數組至少包含一個子文檔,其qty大于30,小于等于50的所有文檔 cursor = db.inventory.find({'instock': {'$elemMatch': {'qty': {'$gt': 30, '$lte': 50}}}} ) """ [{u 'item': u 'planner',u '_id': ObjectId('5c8c5f4abddaf049404c5e8c'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 40}, {u 'warehouse': u 'B',u 'qty': 5}] }, {u 'item': u 'postcard',u '_id': ObjectId('5c8c5f4abddaf049404c5e8d'),u 'instock': [{u 'warehouse': u 'B',u 'qty': 15}, {u 'warehouse': u 'C',u 'qty': 35}] }] """子文檔組合滿足復合查詢條件
如果復合查詢不使用$elemMatch運算符,那么查詢將選擇那些數組包含任何能滿足條件的組合。比如:
# 查詢instock下的某些子文檔的qty字段大于30,且某些子文檔的qty字段小于等于50,(或同時滿足)的所有文檔 # (若instock下的所有文檔的組合都不能滿足以上條件,則無法被過濾出來) cursor = db.inventory.find({'instock.qty': {'$gt': 30, '$lte': 50}} ) """ [{u 'item': u 'paper',u '_id': ObjectId('5c8c5f4abddaf049404c5e8b'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 60}, {u 'warehouse': u 'B',u 'qty': 15}] }, {u 'item': u 'planner',u '_id': ObjectId('5c8c5f4abddaf049404c5e8c'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 40}, {u 'warehouse': u 'B',u 'qty': 5}] }, {u 'item': u 'postcard',u '_id': ObjectId('5c8c5f4abddaf049404c5e8d'),u 'instock': [{u 'warehouse': u 'B',u 'qty': 15}, {u 'warehouse': u 'C',u 'qty': 35}] }] """ # 查詢instock下的某些子文檔的qty字段等于5,且某些子文檔的warehouse等于A,(或同時滿足)的所有文檔 cursor = db.inventory.find({'instock.qty': 5, 'instock.warehouse': 'A' }) """ [{u 'item': u 'journal',u '_id': ObjectId('5c8c5f4abddaf049404c5e89'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 5}, {u 'warehouse': u 'C',u 'qty': 15}] }, {u 'item': u 'planner',u '_id': ObjectId('5c8c5f4abddaf049404c5e8c'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 40}, {u 'warehouse': u 'B',u 'qty': 5}] }] """返回字段
默認情況下,MongoDB的查詢返回匹配文檔的所有字段,如果想限制返回數據的大小,可以使用projection文檔(投影文檔)來指定返回的字段。
準備數據:
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test5db.inventory.insert_many([{"item": "journal","status": "A","size": {"h": 14, "w": 21, "uom": "cm"},"instock": [{"warehouse": "A", "qty": 5}]},{"item": "notebook","status": "A","size": {"h": 8.5, "w": 11, "uom": "in"},"instock": [{"warehouse": "C", "qty": 5}]},{"item": "paper","status": "D","size": {"h": 8.5, "w": 11, "uom": "in"},"instock": [{"warehouse": "A", "qty": 60}]},{"item": "planner","status": "D","size": {"h": 22.85, "w": 30, "uom": "cm"},"instock": [{"warehouse": "A", "qty": 40}]},{"item": "postcard","status": "A","size": {"h": 10, "w": 15.25, "uom": "cm"},"instock": [{"warehouse": "B", "qty": 15},{"warehouse": "C", "qty": 35}]}])我們看以下查詢:
cursor = db.inventory.find({"status": "A"})該查詢相當于SQL的:
SELECT * FROM inventory WHERE status = 'A'只返回指定字段和 _id 字段
在投影文檔中,將需要的字段設置為1,就可以指定查詢后返回的字段。比如:
cursor = db.inventory.find( # find的第二個參數是投影文檔{'status': 'A'}, {'item': 1, 'status': 1} )""" [{u 'status': u 'A',u 'item': u 'journal',u '_id': ObjectId('5c8ca21dbddaf046e0efdd49') }, {u 'status': u 'A',u 'item': u 'notebook',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4a') }, {u 'status': u 'A',u 'item': u 'postcard',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4d') }] """上述查詢相當于SQL:
SELECT _id, item, status from inventory WHERE status = "A"丟棄 _id 字段
_id字段會默認返回,如果不需要,可以在投影文檔中指定 _id: 0
cursor = db.inventory.find({'status': 'A'}, {'item': 1, 'status': 1, '_id': 0} )返回所有字段,排除某些字段
將要排除的字段在投影文檔中設置為0即可
cursor = db.inventory.find({'status': 'A'}, {'status': 0, 'instock': 0} )""" [{u 'item': u 'journal',u '_id': ObjectId('5c8ca21dbddaf046e0efdd49'),u 'size': {u 'h': 14,u 'w': 21,u 'uom': u 'cm'} }, {u 'item': u 'notebook',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4a'),u 'size': {u 'h': 8.5,u 'w': 11,u 'uom': u 'in'} }, {u 'item': u 'postcard',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4d'),u 'size': {u 'h': 10,u 'w': 15.25,u 'uom': u 'cm'} }] """注意:
除了_id字段,projection中不能既有指定字段,又有排除字段。下面的查詢會報錯:
cursor = db.inventory.find({'status': 'A'}, {'status': 0, 'instock': 0, 'item': 1} )""" pymongo.errors.OperationFailure: Projection cannot have a mix of inclusion and exclusion. """返回子文檔中的指定字段
通過.點標記指定嵌套字段并設置為1即可,比如
# 查詢所有文檔,并且只返回size子文檔中的uom字段 cursor = db.inventory.find({}, {'item': 1, 'status': 1, 'size.uom': 1} )""" [{u 'status': u 'A',u 'item': u 'journal',u '_id': ObjectId('5c8ca21dbddaf046e0efdd49'),u 'size': {u 'uom': u 'cm'} }, // ... {u 'status': u 'A',u 'item': u 'postcard',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4d'),u 'size': {u 'uom': u 'cm'} }] """丟棄子文檔中的指定字段
通過.點標記指定嵌套字段并設置為0即可,比如
# 查詢satus等于D的所有文檔,且子文檔不返回uom字段 cursor = db.inventory.find({'status': 'D'}, {'size.uom': 0} )""" [{u 'status': u 'D',u 'item': u 'paper',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4b'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 60}],u 'size': {u 'h': 8.5,u 'w': 11} }, {u 'status': u 'D',u 'item': u 'planner',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4c'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 40}],u 'size': {u 'h': 22.85,u 'w': 30} }] """投射數組內的子文檔指定字段
使用.標記來投影數組內子文檔的字段即可,比如
cursor = db.inventory.find({'status': 'D'}, {'item': 1, 'status': 1, 'instock.qty': 1} )""" [{u 'status': u 'D',u 'item': u 'paper',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4b'),u 'instock': [{u 'qty': 60}] }, {u 'status': u 'D',u 'item': u 'planner',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4c'),u 'instock': [{u 'qty': 40}] }] """投射指定的數組元素
MongoDB為包含數組的字段提供了一些運算符,來操作數組:
$elemMatch, $slice, $
下面使用切片運算符$slice來返回數組中的最后一個元素:
cursor = db.inventory.find({'status': 'A'},{'item': 1, 'status': 1, 'instock': {'$slice': -1}} )""" [{u 'status': u 'A',u 'item': u 'journal',u '_id': ObjectId('5c8ca21dbddaf046e0efdd49'),u 'instock': [{u 'warehouse': u 'A',u 'qty': 5}] }, {u 'status': u 'A',u 'item': u 'notebook',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4a'),u 'instock': [{u 'warehouse': u 'C',u 'qty': 5}] }, {u 'status': u 'A',u 'item': u 'postcard',u '_id': ObjectId('5c8ca21dbddaf046e0efdd4d'),u 'instock': [{u 'warehouse': u 'C',u 'qty': 35}] }] """查詢Null或缺失字段
MongoDB中的不同查詢運算符對null值的處理也不同。
準備數據:
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test6# 插入兩個文檔,一個item為空值,一個item字段缺失 db.inventory.insert_many([{"_id": 1, "item": None}, {"_id": 2}])相等性過濾
{'item': None}查詢將匹配要么item字段為空值,要么不包含item字段的文檔:
cursor = db.inventory.find({'item': None} )""" [{u 'item': None,u '_id': 1 }, {u '_id': 2 }] """類型檢查
{'item': {'$type': 10}}查詢只匹配item為空值的文檔。空值的類型碼是10
cursor = db.inventory.find({'item': {'$type': 10}} )""" [{u'item': None, u'_id': 1}] """存在檢查
{'item': {'$exists': False}}查詢只匹配不包含item字段的文檔
cursor = db.inventory.find({'item': {'$exists': False}} )""" [{u'_id': 2}] """更新文檔
更新文檔主要使用如下幾個方法:
- db.collection.update_one() 最多更新一個文檔(即使匹配出多個)
- db.collection.update_many() 更新所有匹配的文檔
- db.collection.replace_one()最多替換一個文檔(即使匹配出過個)
- db.collection.update()
- 如果匹配處單個文檔,則進行更新或替換
- 如果匹配出多個文檔,則更新這些文檔
準備數據:
db.inventory.insert_many([{"item": "canvas","qty": 100,"size": {"h": 28, "w": 35.5, "uom": "cm"},"status": "A"},{"item": "journal","qty": 25,"size": {"h": 14, "w": 21, "uom": "cm"},"status": "A"},{"item": "mat","qty": 85,"size": {"h": 27.9, "w": 35.5, "uom": "cm"},"status": "A"},{"item": "mousepad","qty": 25,"size": {"h": 19, "w": 22.85, "uom": "cm"},"status": "P"},{"item": "notebook","qty": 50,"size": {"h": 8.5, "w": 11, "uom": "in"},"status": "P"},{"item": "paper","qty": 100,"size": {"h": 8.5, "w": 11, "uom": "in"},"status": "D"},{"item": "planner","qty": 75,"size": {"h": 22.85, "w": 30, "uom": "cm"},"status": "D"},{"item": "postcard","qty": 45,"size": {"h": 10, "w": 15.25, "uom": "cm"},"status": "A"},{"item": "sketchbook","qty": 80,"size": {"h": 14, "w": 21, "uom": "cm"},"status": "A"},{"item": "sketch pad","qty": 95,"size": {"h": 22.85, "w": 30.5, "uom": "cm"},"status": "A"}])更新集合中的文檔
如果要修改字段的值,可以使用更新運算符,比如$set,基本格式如下:
{<更新運算符>: {<字段1>: <值1>, ...},<更新運算符>: {<字段2>: <值2>, ...}, }更新單個文檔:update_one()
res = db.inventory.update_one({'item': 'paper'}, # filter{ # update'$set': {'size.uom': 'cm','status': 'P'},'$currentDate': {'lastModified': True # 新增lastModified字段,值是當前時間}} )print(res) # <pymongo.results.UpdateResult object at 0x0000024A22FFB3C8> print(res.matched_count) # 1 print(res.modified_count) # 1cursor = db.inventory.find({'item': 'paper'}) docs = [doc for doc in cursor] print(docs) """ [{'_id': ObjectId('5c8f8dcfbddaf03aa4b6a409'),'item': 'paper','qty': 100,'size': {'h': 8.5,'w': 11,'uom': 'cm'},'status': 'P','lastModified': datetime.datetime(2019, 3, 18, 12, 36, 45, 391000) }] """更新多個文檔:update_many()
# 更新qty小于50的文檔 res = db.inventory.update_many({'qty': {'$lt': 50}}, # filter{ # update'$set': {'size.uom': 'in', 'status': 'P'},'$currentDate': {'lastModified': True}} )print(res) # <pymongo.results.UpdateResult object at 0x0000014249CF7488> print(res.matched_count) # 3 print(res.modified_count) # 3cursor = db.inventory.find({'qty': {'$lt': 50}}) docs = [doc for doc in cursor] print(docs) """ [{'_id': ObjectId('5c8f8dcfbddaf03aa4b6a405'),'item': 'journal','qty': 25,'size': {'h': 14,'w': 21,'uom': 'in'},'status': 'P','lastModified': datetime.datetime(2019, 3, 19, 12, 26, 33, 410000) }, {'_id': ObjectId('5c8f8dcfbddaf03aa4b6a407'),'item': 'mousepad','qty': 25,'size': {'h': 19,'w': 22.85,'uom': 'in'},'status': 'P','lastModified': datetime.datetime(2019, 3, 19, 12, 26, 33, 413000) }, {'_id': ObjectId('5c8f8dcfbddaf03aa4b6a40b'),'item': 'postcard','qty': 45,'size': {'h': 10,'w': 15.25,'uom': 'in'},'status': 'P','lastModified': datetime.datetime(2019, 3, 19, 12, 26, 33, 414000) }] """替換文檔:replace_one()
如果要替換整個文檔的內容(除了_id字段),只需傳入一個新的文檔,作為replace_one()的第二個參數即可。替換的文檔只能包含鍵值對,不能巴博涵其他表達式,比如更新運算符。替換的文檔可以和原文的的字段不同,由于_id不可變,你可以省略_id字段(當然,如果你非要在替換文檔中包含_id字段,那么必須給出與原文檔一樣的值)
# 替換滿足篩選條件的第一個文檔 res = db.inventory.replace_one({'item': 'paper'}, # filter{'item': 'paper', # replacement_doc'instock': [{"warehouse": "A", "qty": 60},{"warehouse": "B", "qty": 40}]} )print(res) # <pymongo.results.UpdateResult object at 0x000001AD62170448> print(res.matched_count) # 1 print(res.modified_count) # 1cursor = db.inventory.find({'item': 'paper'}) docs = [doc for doc in cursor] print(docs) """ [{'_id': ObjectId('5c8f8dcfbddaf03aa4b6a409'),'item': 'paper','instock': [{'warehouse': 'A','qty': 60}, {'warehouse': 'B','qty': 40}] }] """更新行為
原子性
MongoDB的所有寫操作在單個文檔上都是原子性的。
_id字段
一旦設置,該字段的值不可修改,也不能被替換。
字段順序
MongoDB保持寫操作中文檔的順序,除了以下情況:
- _id字段總是文檔中的第一個字段
- 如果更新包含對字段進行命名的操作,可能導致文檔的字段重新排序
upsert選項
調用update_one(), update_many(), replace_one()這些方法時,如果指定upsert=True,那么當匹配的文檔不存在時,將創建新的文檔并插入。
刪除文檔
刪除文檔的方法:
- db.collection.deleteOne() 最多刪除一個文檔(即便匹配出多個結果)
- db.collection.deleteMany() 刪除匹配的所有文檔
- db.collection.remove() 刪除匹配的單個或多個文檔
準備數據:
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test8db.inventory.insert_many([{"item": "journal","qty": 25,"size": {"h": 14, "w": 21, "uom": "cm"},"status": "A"},{"item": "notebook","qty": 50,"size": {"h": 8.5, "w": 11, "uom": "in"},"status": "P"},{"item": "paper","qty": 100,"size": {"h": 8.5, "w": 11, "uom": "in"},"status": "D"},{"item": "planner","qty": 75,"size": {"h": 22.85, "w": 30, "uom": "cm"},"status": "D"},{"item": "postcard","qty": 45,"size": {"h": 10, "w": 15.25, "uom": "cm"},"status": "A"}])刪除所有文檔
如果要刪除所有文檔,只需給delete_many()方法的filter傳入一個空文檔即可
res = db.inventory.count_documents({}) # 查看所有文檔數 print(res) # 5 res = db.inventory.delete_many({}) print(res.deleted_count) # 5刪除滿足條件的所有文檔
只需給delete_many()方法的filter傳入過濾條件即可,比如
# 刪除status是A點所有文檔 res = db.inventory.delete_many({'status': 'A'}) print(res.deleted_count) # 2只刪除滿足條件的一個文檔
count = db.inventory.count_documents({'status': 'D'}) cursor = db.inventory.find({'status': 'D'}) print(count) # 2 print([item for item in cursor]) """ [{'_id': ObjectId('5c922bb5bddaf04be0e84076'),'item': 'paper','qty': 100,'size': {'h': 8.5,'w': 11,'uom': 'in'},'status': 'D' }, {'_id': ObjectId('5c922bb5bddaf04be0e84077'),'item': 'planner','qty': 75,'size': {'h': 22.85,'w': 30,'uom': 'cm'},'status': 'D' }] """db.inventory.delete_one({'status': 'D'}) count = db.inventory.count_documents({'status': 'D'}) cursor = db.inventory.find({'status': 'D'}) print(count) print([item for item in cursor]) # 滿足條件的第一個文檔已被刪除 """ [{'_id': ObjectId('5c922bb5bddaf04be0e84077'),'item': 'planner','qty': 75,'size': {'h': 22.85,'w': 30,'uom': 'cm'},'status': 'D' }] """刪除行為
索引
刪除操作不會刪除索引,即使從表中刪除所有文檔。
原子性
單個文檔的級別上是原子性操作。
批量寫操作:
批量寫操作只對單個集合有效。insert_many()能進行批量插入,另外,bulk_write()方法支持如下的多種寫操作:
- insert_one
- update_one
- update_many
- replace_one
- delete_one
- delete_many
將每種操作放在列表中,然后傳給bulk_write()
下面我們來試一下,準備數據:
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test8res = db.characters.insert_many([{"_id": 1, "char": "Brisbane", "class": "monk", "lvl": 4},{"_id": 2, "char": "Eldon", "class": "alchemist", "lvl": 3},{"_id": 3, "char": "Meldane", "class": "ranger", "lvl": 3} ])print(res.inserted_ids) # [1, 2, 3]使用bulk_write()對characters集合執行多個操作:
import pymongo from pymongo import InsertOne, UpdateOne, DeleteOne, ReplaceOne # 導入各操作對象client = pymongo.MongoClient('mongodb://localhost:27017/') db = client.test8try:res = db.characters.bulk_write([InsertOne({'_id': 4, 'char': 'Dithras', 'class': 'barbarian', 'lvl': 4}),InsertOne({'_id': 5, 'char': 'Taeln', 'class': 'fighter', 'lvl': 3}),UpdateOne({'char': 'Eldon'},{'$set': {'status': 'Critical Injury'}}, upsert=True),UpdateOne({'char': 'Ayhan'},{'$set': {'status': 'God hit'}}, upsert=True),ReplaceOne({'char': 'Meldane'},{"char": "Tanys", "class": "oracle", "lvl": 4}, upsert=True),DeleteOne({'char': 'Brisbane'}),])print(res.inserted_count) # 2print(res.modified_count) # 2print(res.upserted_count) # 1print(res.deleted_count) # 1# 以上打印方式比較繁瑣,也可以這樣直接打印本次批量操作的詳細信息:print(res.bulk_api_result) except Exception as e:print(e)cursor = db.characters.find({}) print([item for item in cursor]) """ [{'_id': 2,'char': 'Eldon','class': 'alchemist','lvl': 3,'status': 'Critical Injury' }, {'_id': 3,'char': 'Tanys','class': 'oracle','lvl': 4 }, {'_id': 4,'char': 'Dithras','class': 'barbarian','lvl': 4 }, {'_id': 5,'char': 'Taeln','class': 'fighter','lvl': 3 }, {'_id': ObjectId('5c92fc403744b8cc2b23f3c3'),'char': 'Ayhan','status': 'God hit' }] """分片集合的批量插入策略
暫不討論。
索引
添加索引可以加速特定的查詢,也可以為文檔在查詢和存儲增加額外的功能。下面演示下如何用PyMongo創建unique索引:
db.user.create_index([('user_id', pymongo.ASCENDING) ], unique=True)print(list(db.user.index_information())) """ ['_id_', 'user_id_1']_id_ 是MongoDB自動創建的索引 user_id_1 是我們剛剛創建的索引 """創建了唯一索引約束后,如果插入數據的user_id字段的值在集合中已經存在,會插入失敗。
聚合
準備數據:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.test9db.things.insert_many([{'x': 1, 'tags': ['dog', 'cat']},{'x': 2, 'tags': ['cat']},{'x': 2, 'tags': ['mouse', 'cat', 'dog']},{'x': 3, 'tags': []}, ])Pipeline聚合
下面執行一個簡答的聚合操作,統計集合內tags數組內每個元素的出現次數。要實現這個操作,需要傳入3個操作給pipeline,首先展開tags數組,然后按元素進行分組并加總,最后根據加總數進行排序即可。
注意,由于python的字典是無序的,如果要求精確排序(比如$sort),就得使用SON或者collections.OrderedDict對象:
import pymongo from bson.son import SON import pprintclient = pymongo.MongoClient(host='localhost', port=27017) db = client.test9pipeline = [{'$unwind': '$tags'},{'$group': {'_id': '$tags', 'count': {'$sum': 1}}}, # 以元素作為_id字段的值,以元素個數作為count字段的值,1表示正加總(-1則進行負加總){'$sort': SON([('count', -1), ('_id', -1)])} # 先按count, 再按_id排序,-1表示倒序 ] pprint.pprint(list(db.things.aggregate(pipeline))) """ [{'_id': 'cat', 'count': 3},{'_id': 'dog', 'count': 2},{'_id': 'mouse', 'count': 1}] """# 如果顛倒排序順序為: {'$sort': SON([('_id', -1), ('count', -1)])},結果如下: """ [{'_id': 'mouse', 'count': 1},{'_id': 'dog', 'count': 2},{'_id': 'cat', 'count': 3}] """# 如果想查看該操作的詳細信息,可以使用command()方法: res = db.command('aggregate', 'things', pipeline=pipeline, explain=True) pprint.pprint(res) """ {'ok': 1.0,'stages': [{'$cursor': {'fields': {'_id': 0, 'tags': 1},'query': {},'queryPlanner': {'indexFilterSet': False,'namespace': 'test9.things','parsedQuery': {},'plannerVersion': 1,'rejectedPlans': [],'winningPlan': {'direction': 'forward','stage': 'COLLSCAN'}}}},{'$unwind': {'path': '$tags'}},{'$group': {'_id': '$tags', 'count': {'$sum': {'$const': 1}}}},{'$sort': {'sortKey': {'_id': -1, 'count': -1}}}]} """聚合框架還可以提供投影能力來重塑返回的數據。利用投影和聚合,你可以在結果中增加計算字段,創建虛擬子對象,或者提取子字段為根級字段。更多查看:聚合框架
Map / Reduce 聚合
另一種實現聚合的方式是使用map reduce,下面我們通過定義map和reduce函數來實現上面的聚合計算。
map函數循環數組,對其中的每個元素觸發一個鍵值對兒(key, 1):
高級 Map / Reduce
寫入重試
寫操作時,如果發生網絡錯誤,是否支持重試。在pymongo中,可以在實例化客戶端時指定,比如:
client = pymongo.MongoClient(host='localhost',port=27017,retryWrites=True # 默認是False,具體可以查看源碼中的doc )文本搜索
MongoDB支持通過$text運算符對文本字段作索引,以方便文本搜索。不過嘛,不支持中文,洗洗睡。。。
運算符列表:
| $or | 邏輯或 |
| $eq | 等于 |
| $gt | 大于 |
| $gte | 大于等于 |
| $in | 在數組中 |
| $lt | 小于 |
| $lte | 小于等于 |
| $ne | 不等于 |
| $nin | 不在數組中 |
| $elemMatch | 數組元素滿足 |
| $all | 數組包含元素 |
| $slice | 數組切片 |
| $type | 字段值類型檢查 |
| $exists | 字段是否存在判斷 |
| $set | 更新字段的值 |
| $currentDate | 設定某字段的值為當前日期時間 |
| $inc | 增加某字段的值 |
| $push | 為數組字段添加新的元素 |
mongoengine
待完善。
總結
以上是生活随笔為你收集整理的mongo数据库CRUD的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二叉树两个结点的最低公共父结点 【微软面
- 下一篇: Redis实现求交集操作结果缓存的设计方