MongoDB的查找最重要的函數(shù)是find
find()函數(shù)第一個參數(shù)是查找文檔,第二個參數(shù)可以限制返回的鍵
查詢條件
'$lt' $lte $gt $gte
使用 分別代表< 、<=、>唯卖、>=
$ne
表示不相等
我的docs 是這樣組織的
doc ={
'title':title,
'description':desc,
'classname':classname,
'pdflocation':pdf_path,
'sourcelocation':source_path,
'uploadtime':time.strftime('%F %X',time.localtime(time.time())),
'downloadcount':0,
'username':username,
'cover':"",
'recentDownload':[],
}
查找某一個條件可以這樣寫
#連接數(shù)據(jù)庫操作 語言為python
from pymongo import Connection
#連接到test數(shù)據(jù)庫,MongoDB默認自帶的測試數(shù)據(jù)庫
db = Connection("localhost", 27017).test
db.docs.find({'title':'hehe'})
當(dāng)然我也可以限制只返回pdflocation
db.docs.find({'title':'hehe'}蚌铜,{'pdflocation':1})
或者除了pdflocation都要
db.docs.find({'title':'hehe'},{'pdflocation':0})
上面的操作返回docs數(shù)據(jù)集中title 為hehe的文檔
如果我想找到時間在某一個范圍內(nèi)的doc,我可以這樣寫
docs = db.docs.find({'uploadtime':{
'$lte':time.strftime('%F %X',time.localtime(time.time())),
'$gt':time.strftime('%F %X',time.localtime(time.time())),
}
})
當(dāng)然既小于當(dāng)前時間又大于當(dāng)前時間的doc肯定不錯在了鳄虱,所以返回None
像上面的查詢文檔中的關(guān)系類似 sql中的where A and B
那么要查找where a or b 該怎么辦诗力?
或關(guān)系查找
使用 $in
或者 $or
比如我想查找文檔中名字是 test1 或 test2的 可以這樣
docs = db.docs.find({'title':{
'$in':['test1','test2'],
}
})
對于某個鍵的或查找凰浮,這樣效率是很不錯的
相對應(yīng)的還有nin
not in 不在這個里面的 很容易理解
那么要找題目(title)或者描述(description)是test的怎么查找呢?
用$or
需要注意的是$or
后面需要的是一個list 苇本,list每一項就是一個或的一個條件
docs = db.docs.find({
'$or':[{'title':'test'},{'description':'test'}]
})
邏輯操作
有了$or
當(dāng)然也由其他邏輯操作符號
$not
取反 與正則表達式一起使用將極為高效
$and
很少使用 默認在一個{}中的條件都是and關(guān)系
這幾個使用基本相同 后面都需要接一個數(shù)組
數(shù)組的每一項都是字典袜茧,里面是進行邏輯組合的條件
模糊搜索
使用要使用像Sql中 where A like "%s% " 可以使用正則表達式來匹配
Mongodb支持于Perl兼容的正則表達式來匹配字符串
在python的pymongo這個庫中可以這樣寫
利用re模塊
docs = db.docs.find({'title':re.compile('[\w]+')})
或者利用$regex
docs = db.docs.find({'title':{'$regex':'[\w]+'}})
這樣就支持了我在py中用的正則表達式了
鍵的值非空
傳統(tǒng)Sql數(shù)據(jù)中一般都由Null字段
MongoDB也是有的,在python中對應(yīng)的是None
查找名字非空的文檔
docs = db.docs.find({'title':{'$ne':None}})
查找名字為空的文檔
docs = db.docs.find({'title':{'$in':[None]}})
查詢數(shù)組
MongoDB中某個鍵的值是list是是經(jīng)常使用的瓣窄,比如doc
recentDownload 字段是一個list笛厦,每次有人下載該文檔,
都將下載者的di放到這個list 中(很不推薦這樣做俺夕,這只是個例子
比如 coco裳凸、joe贱鄙、tom最近下載了這個文檔
那么
docs = db.docs.find({'recentDownload':'coco'})
docs = db.docs.find({'recentDownload':'joe'})
都將返回這個文檔
那么如果想找到coco和tom最近都下載了哪個文檔
需要用$all
docs = db.docs.find({'recentDownload':{'$all':['coco','tom']}})
并且all后面的數(shù)組的順序不影響結(jié)果
當(dāng)然你也可以精確匹配
docs = db.docs.find('recentDownload':['coco','joe'])
這里的['coco','joe']是一個元素 除非recentDownload完全等于這個list,否則不會匹配
如果知道順序也可以這樣查找
查找recentDownload2的第二個元素是coco
docs = db.docs.find('recentDownload.2':'coco')
使用$size
可以查找到特定長度的數(shù)組
文檔被下載的次數(shù)越來越多姨谷,這個list也越來大逗宁,如果只想知道最近哪十個人下載了這個文檔
可以在更新指定這個list的大小,也可以在查詢時用$slice
來限制返回的數(shù)量
從前到后的10個
docs = db.docs.find({'recentDownload':{'$slice':10}})
我們想要最近下載的十個人的id 那么
但是在python中報錯了
pymongo.errors.OperationFailure: database error: Can't canonicalize query: BadValue unknown operator: $slice
懷疑pymongo不支持
docs = db.docs.find({'recentDownload':{'$slice':-10}})
就可以了
查詢數(shù)組與范圍查詢的相互影響
我們現(xiàn)在由這樣的文檔
{'x': 5 }
{'x': 15 }
{'x': 25 }
{'x': [5,25 }
執(zhí)行這樣的查詢
docs = db.testDoc.find({'x':{'$gt':6,'$lt':24}})
發(fā)現(xiàn)輸出
{u'x': 15, u'_id': ObjectId('54815f29348e3b14df008c41')}
{u'x': [5, 25], u'_id': ObjectId('54815f29348e3b14df008c43')}
不應(yīng)該安っ搿疙剑! 5 和25 都不在這個范圍啊践叠!
原因在于:
5滿足小于24 6滿足大于5的條件言缤,故這個文檔被返回了
這時候需要使用$elemMatch
操作符
這時候返回空
..因為$elemMatch只搜索數(shù)組
解決這個問題的方法需要使用“索引”
查詢內(nèi)聯(lián)文檔
一個鍵的值出了可以是一個list之外,當(dāng)然可以是一個文檔(dict)了
比如文檔作者可以由名字和性別組成
{'author':{
'name':'coco',
'sex':'f'
}}
那么可以這樣搜索
查詢author的名字為coco的文檔
docs = db.testDoc.find({'author.name':'coco'})
但是如果這個coco有男有女怎么辦呢禁灼?
和list時一樣一個dict要滿足所有條件需要使用$elemMatch
注 這里發(fā)生了些許問題管挟,問題的原因不明,正在尋找問題的原因
docs = db.testDoc.find({'author':{'$elemMatch':{'name':'coco','sex':'f'}}})
如果使用javascript 還可以在$where
語句之后添加函數(shù) 弄捕,相當(dāng)牛X