MongoDB查找語法

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末僻孝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子守谓,更是在濱河造成了極大的恐慌穿铆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斋荞,死亡現(xiàn)場離奇詭異荞雏,居然都是意外死亡,警方通過查閱死者的電腦和手機平酿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門凤优,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜈彼,你說我怎么就攤上這事筑辨。” “怎么了幸逆?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵棍辕,是天一觀的道長。 經(jīng)常有香客問我秉颗,道長痢毒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任蚕甥,我火速辦了婚禮哪替,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菇怀。我一直安慰自己凭舶,他們只是感情好晌块,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帅霜,像睡著了一般匆背。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上身冀,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天钝尸,我揣著相機與錄音,去河邊找鬼搂根。 笑死珍促,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的剩愧。 我是一名探鬼主播猪叙,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼仁卷!你這毒婦竟也來了穴翩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤锦积,失蹤者是張志新(化名)和其女友劉穎芒帕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丰介,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡副签,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了基矮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡冠场,死狀恐怖家浇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碴裙,我是刑警寧澤钢悲,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站舔株,受9級特大地震影響莺琳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜载慈,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一惭等、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧办铡,春花似錦辞做、人聲如沸琳要。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稚补。三九已至,卻和暖如春框喳,著一層夾襖步出監(jiān)牢的瞬間课幕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工五垮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乍惊,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓拼余,卻偏偏與公主長得像污桦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匙监,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容