mongodb 监听不到端口_干货|MongoDB简单操作和通过python进行操作
點擊上方“AI遇見機器學習”,選擇“星標”公眾號
重磅干貨,第一時間送達
這次我們主要來簡單的討論一下在MongoDB中如何更新數據(修改數據),刪除數據,以及如何通過Python調用MongoDB。
一、簡單使用MongoDB操作數據
| a.更新數據
| i.數據更新
更新集合中的數據使用update(CONDITION,OPERATE)命令,它接收兩個參數,前者為條件,后者為進行更新的操作:
> db.asd.insert({x:1})WriteResult({ "nInserted" : 1 })
> db.asd.find()
{ "_id" : ObjectId("5961087fd4fd4ce8ff6ca18a"), "x" : 1 }
> db.asd.update({x:1},{x:2})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.asd.find()
{ "_id" : ObjectId("5961087fd4fd4ce8ff6ca18a"), "x" : 2 }
如上例,將文檔中有x:1的改成x:2。
| ii.局部更新
有些時候,我們需要對文檔進行局部更新,MongoDB中,默認一般情況的修改會對整個文檔造成影響
> db.asd.insert({x:1,y:1,z:1})WriteResult({ "nInserted" : 1 })
> db.asd.update({x:1},{y:2})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.asd.find()
{ "_id" : ObjectId("59610918d4fd4ce8ff6ca18b"), "y" : 2 }
例如上面的例子,我們只想對{x:1,y:1,z:1}進行修改使得y:1變為y:2,但如果直接使用update()會使得整個文檔被修改的只剩下y:1。
這個時候,就需要使用$set來對文檔進行局部更新
> db.asd.update({x:1},{$set:{y:2}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.asd.find()
{ "_id" : ObjectId("596109e0d4fd4ce8ff6ca18c"), "x" : 1, "y" : 2, "z" : 1 }
| iii.更新不存在的數據
有時候,我們需要直接更新一條數據庫中并不存在的數據,這個時候,僅僅用原來的update()的使用方法是達不到效果的,我們需要在括號里面加上第三個參數(Bool)來實現我們想要的效果
> db.zyzy.find()> db.zyzy.update({x:1},{y:1},true)
WriteResult({
? ? ? ?"nMatched" : 0,
? ? ? ?"nUpserted" : 1,
? ? ? ?"nModified" : 0,
? ? ? ?"_id" : ObjectId("5961b6f09f1fbf45940b7f04")
})
> db.zyzy.find()
{ "_id" : ObjectId("5961b6f09f1fbf45940b7f04"), "y" : 1 }
|?iv.更新多條數據
update在使用的時候,默認只更新被查找到的第一條數據,這是為了防止用戶進行誤操作。
> for(i=0;i<3;i++)db.zyzy.insert({x:1})WriteResult({ "nInserted" : 1 })
#插入三條x為1的文檔
> db.zyzy.update({x:1},{x:2})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.zyzy.find()
{ "_id" : ObjectId("5961b7fe540435d89b5c5eca"), "x" : 2 }
{ "_id" : ObjectId("5961b7fe540435d89b5c5ecb"), "x" : 1 }
{ "_id" : ObjectId("5961b7fe540435d89b5c5ecc"), "x" : 1 }
發現只有第一個文檔被更新了。
要同時更新多條數據,就需要使用update()的第四個也是最后一個參數(Bool)。
> db.zyzy.update({x:1},{$set:{x:2}},false,true)WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
> db.zyzy.find()
{ "_id" : ObjectId("5961b7fe540435d89b5c5eca"), "x" : 2 }
{ "_id" : ObjectId("5961b7fe540435d89b5c5ecb"), "x" : 2 }
{ "_id" : ObjectId("5961b7fe540435d89b5c5ecc"), "x" : 2 }
這里的更新方式通常都是使用局部更新的方式,也是為了防止誤操作。
| b.數據刪除
要刪除集合中的數據,我們使用remove()方法,它接收一個參數,作為查找刪除數據的條件,該參數不能為空。如果想清除集合里面的所有數據,可以直接時候用drop()廢除集合。
> db.test_collection.find(){ "_id" : ObjectId("5961b9d8540435d89b5c5ecd"), "x" : 1 }
{ "_id" : ObjectId("5961b9e9540435d89b5c5ece"), "x" : 1 }
{ "_id" : ObjectId("5961b9e9540435d89b5c5ecf"), "x" : 1 }
{ "_id" : ObjectId("5961b9e9540435d89b5c5ed0"), "x" : 1 }
> db.test_collection.remove({x:1})
WriteResult({ "nRemoved" : 4 })
> db.test_collection.find()
但也有時候我們只想刪除被找到的第一條數據,這個時候可以利用remove的第二個參數
> for(i=0;i<10;i++)db.test_collection.insert({x:i})WriteResult({ "nInserted" : 1 })
> db.test_collection.remove({x:{$type:1}},true)
WriteResult({ "nRemoved" : 1 })
> db.test_collection.find()
{ "_id" : ObjectId("5961e9c7e12ea99cbdc056a4"), "x" : 1 }
{ "_id" : ObjectId("5961e9c7e12ea99cbdc056a5"), "x" : 2 }
{ "_id" : ObjectId("5961e9c7e12ea99cbdc056a6"), "x" : 3 }
{ "_id" : ObjectId("5961e9c7e12ea99cbdc056a7"), "x" : 4 }
...
二、安裝pymongo與連接MongoDB
接下來我們介紹如何在Python中使用MongoDB。
要通過Pyhton使用MongoDB,我們首先需要下載Python用于操作MongoDB的庫pymongo
pip install pymongo然后就可以在python中導入這個庫了,不過通常我們只是導入它的驅動:
from pymongo import MongoClien導入之后,我們在Python中通過下面一段代碼獲取MongoDB的操作對象:
client=MongoClient('127.0.0.1',27017) #建立和數據庫的連接,前者是MongoDB服務所在的地址,后者是對應的端口號db_auth=client.admin #指定使用哪個數據庫的賬號,這里用的是數據庫admin
db_auth.authenticate("admin","password") #權限認證,第一個參數是賬號,第二個參數是密碼
#若連接的數據庫不需要賬號,上述兩條可以省略。
db_name="test" #要連接的數據庫的名字
db = client[db_name] #獲得數據庫操作對象,也可以寫作`client.db_name`
collection_useraction=db['useraction'] #獲得數據庫的集合操作對象,集合名為“useraction”
獲得集合操作對象之后,我們就可以通過這個集合操作對象對數據庫的集合進行操作,以上例為例,就是對名為MongoDB的數據庫“test”中名為“useraction”的集合進行操作。
三、在Python中操作MongoDB
| a.插入數據
往集合插入數據的方法有兩種,分別是insert()和save(),對應的就是MongoDB Shell里面的insert()和save()。
它們之間的區別就是,insert()在插入和原來信息重復的數據對象的時候,會報錯,而save()則會將原來的數據對象進行更新。當然,這里的重復指的是唯一索引的重復,類似于“_id”的重復。
collection_useraction.insert({"x":1}用shell查看,發現插入成功
> db.useraction.find(){ "_id" : ObjectId("59635e3a867e573b0c7c8d71"), "x" : 1 }collection_useraction.insert({"x":1,"_id":1})
>...
pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: test.useraction index: _id_ dup key: { : 1 }
#在已有"_id"為1的數據的時候插入一條上述數據,發現編譯器報錯
在python中的insertMany()方法語法為insert_many()
可以發現,python中對MongoDB插入數據的方式與MongoDB Shell沒有太多區別。
| b.更新數據
更新數據使用update()方法,語法格式如下:
update(criteria, objNew, upsert, mult)criteria: 需要被更新的條件表達式
objNew: 更新表達式
upsert: 如目標記錄不存在,是否插入新文檔。
multi: 是否更新多個文檔。
示例:
collection_useraction.update({"x":{"$lt":2}},{"$set":{"y":2}},upsert=True發現操作符的使用方式也與shell沒有太多區別。
| c.刪除數據
| i.刪除集合
要刪除一個集合,有多種方法,方法一是用:
db.collection_name.drop()這個地方的collection_name指的是這個集合在MongoDB數據庫里面的名字,例如我們上面的例子,它的名字就是“useraction”,而不是“collection_useraction”。
另外一個方法是用:
collection_operator.drop()collection_operator指的就是python中該集合的操作對象,如上例,就是“collection_useraction”,而不是集合名字“useraction”
| ii.刪除文檔
刪除文檔使用remove()方法,同樣有兩種方式調用,與上文中刪除集合類似,所以這里只講一種方法:
collection_operator.remove(self, spec_or_id=None, multi=True, **kwargs)第一個參數表示要刪除的文檔的搜索條件或者該文檔的id,默認為None。
multi表示是否刪除多個,為False的時候一次只刪除一個。
當括號為空的時候會刪除集合內所有文檔,這一點與shell不同。
表示刪除所有集合中“x”值為1的文檔。| d.查找數據
| i.find與cursor
我們先假設我們在集合中插入了100條信息
i=0while i<100:
? ?collection_useraction.insert({"x":i,"y":100-i})
? ?i+=1
在Python中查找用的方法同樣也是find(),使用方式也與shell相同,當我們需要查找并遍歷查找結果的時候,可以用這樣的方式:
for u in collection_useraction.find({"x":{"$exists":True}}):? ?print u
>{u'y': 100, u'x': 0, u'_id': ObjectId('59636678867e5717981f18c1')}
{u'y': 99, u'x': 1, u'_id': ObjectId('59636678867e5717981f18c2')}
{u'y': 98, u'x': 2, u'_id': ObjectId('59636678867e5717981f18c3')}
...
這是因為語句collection_useraction.find({"x":{"$exists":True}})返回了一個可供迭代的對象,用type()方法可以看到這個對象的類型:
cursor=collection_useraction.find({"x":{"$exists":True}})print type(cursor)
>
這個對象同時還支持我們直接用索引訪問:
print cursor[10]>{u'y': 90, u'x': 10, u'_id': ObjectId('59636678867e5717981f18cb')}
并且還支持一些shell的方法:
print cursor.explain()>{u'executionStats': {u'executionTimeMillis': 0, u'nReturned': 100, u'totalKeysExamined': 0, u'allPlansExecution': [], u'executionSuccess': True, u'executionStages': {u'needYield': 0, u'direction': u'forward', u'saveState': 0, u'restoreState': 0, u'isEOF': 1, u'docsExamined': 100, u'nReturned': 100, u'needTime': 1, u'filter': {u'x': {u'$exists': True}}, u'executionTimeMillisEstimate': 0, u'invalidates': 0, u'works': 102, u'advanced': 100, u'stage': u'COLLSCAN'}, u'totalDocsExamined': 100}, u'queryPlanner': {u'parsedQuery': {u'x': {u'$exists': True}}, u'rejectedPlans': [], u'namespace': u'test.useraction', u'winningPlan': {u'filter': {u'x': {u'$exists': True}}, u'direction': u'forward', u'stage': u'COLLSCAN'}, u'indexFilterSet': False, u'plannerVersion': 1}, u'ok': 1.0, u'serverInfo': {u'host': u'iPhone', u'version': u'3.4.6', u'port': 27017, u'gitVersion': u'c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5'}}
并且可以對它進行深拷貝:
gg=cursor.clone()aa=cursor
print aa == cursor
print gg == cursor
>True
False
若是想一次只查找一條信息,可以使用方法find_one()。
| ii.查詢特定鍵
當我們只想查詢指定的關鍵字的值的時候,就需要用到find()的第二個參數“projection”:
cursor=collection_useraction.find({},{"x":1})print cursor[10]
>{u'x': 10, u'_id': ObjectId('59636678867e5717981f18cb')}
cursor=collection_useraction.find({},projection={"x":1})
print cursor[10]
>{u'x': 10, u'_id': ObjectId('59636678867e5717981f18cb')}
| iii.排序
排序用的同樣是方法sort(),但是使用方式與shell略有不同:
useraction.find().sort([("KEY",)])“KEY”指作為排序基準的關鍵字的名字,則表示排序的方法,有兩個選項,分別是pymongo.ASCENDING(升序,可用1代替)和pymongo.DESCENDING(降序,可用-1代替)對象,示例:
for u in collection_useraction.find().sort([("x",pymongo.DESCENDING)]):? ?print u
>{u'y': 1, u'x': 99, u'_id': ObjectId('59636679867e5717981f1924')}
{u'y': 2, u'x': 98, u'_id': ObjectId('59636679867e5717981f1923')}
{u'y': 3, u'x': 97, u'_id': ObjectId('59636679867e5717981f1922')}
{u'y': 4, u'x': 96, u'_id': ObjectId('59636679867e5717981f1921')}
...
也可以直接使用find()方法中的sort參數:
for u in collection_useraction.find(sort=[("x",pymongo.DESCENDING)]):? ?print u
| iv.切片
在shell中我們使用skip()與limit()方法來對查詢結果進行切片,python中一樣可以:
for u in collection_useraction.find().skip(90).limit(3):? ?print u
>{u'y': 10, u'x': 90, u'_id': ObjectId('59636679867e5717981f191b')}
{u'y': 9, u'x': 91, u'_id': ObjectId('59636679867e5717981f191c')}
{u'y': 8, u'x': 92, u'_id': ObjectId('59636679867e5717981f191d')}
skip與limit同樣支持參數寫法。
不僅如此,我們還可以對查詢結果使用索引切片:
for u in collection_useraction.find()[2:5]:? ?print u
>{u'y': 98, u'x': 2, u'_id': ObjectId('59636678867e5717981f18c3')}
{u'y': 97, u'x': 3, u'_id': ObjectId('59636678867e5717981f18c4')}
{u'y': 96, u'x': 4, u'_id': ObjectId('59636678867e5717981f18c5')}
| v.正則查詢
在查詢文本的時候,除了MongoDB原有的文本查詢格式,我們還可以使用正則表達式:
pattern=re.compile(r"aa*")for u in collection_useraction.find({"x":pattern}):
? ?print u
>{u'x': u'aa bb cc dd', u'_id': ObjectId('596377bd687384c0a1b9d5e9')}
#下面這個查詢方式顯然shell中也是支持的
for u in collection_useraction.find({"x":{"$regex":r"aa b{2} c{1,3} dd"}}):
? ?print u
>{u'x': u'aa bb cc dd', u'_id': ObjectId('596377bd687384c0a1b9d5e9')}
推薦閱讀
干貨|學術論文怎么寫
資源|NLP書籍及課程推薦(附資料下載)
干貨|全面理解N-Gram語言模型
資源|《Machine Learning for OpenCV》書籍推薦
歡迎關注我們,看通俗干貨!
總結
以上是生活随笔為你收集整理的mongodb 监听不到端口_干货|MongoDB简单操作和通过python进行操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python怎么一直循环_python
- 下一篇: goland 方法注释_goland 设