【MongoDB系列】:MongoDB 查詢應用

find介紹

MongoDB中使用find來進行查詢。查詢就是返回一個集合中文檔的子集,子集得範圍從0個文檔到整個集合。find得第一個參數決定要返回哪些文檔,這個參數是一個文檔,用於指定查詢條件。正則表達式

空得查詢文檔{}默認返回所有內容。 如:db.blog.find() 或者db.blog.find({"name":"zhangsan","age":20})shell

指定須要返回的鍵

    有時候並不須要將文檔中全部的鍵/值對都返回。咱們能夠經過設置第二個參數來指定想要的鍵,這樣會介紹傳輸的數據量,又能節省客戶端解析文檔的時間和內存消耗。
數據庫

    如:db.blog.find({},{"username":1,"email":1})
數組

    默認狀況下,「_id」這個鍵老是被返回的。安全

    也可使用第二個參數來剔除查詢結果中得某些鍵值對。如 db.blog.find({},{"delFlag":0})
服務器

限制

    查詢時候有些限制,傳遞給數據庫的查詢文檔的值必須是常量,不能是陰影文檔中其餘鍵的值。ui

查詢條件

基本操做符

    "$lt","$lte","$gt","$gte"等價於"<","<=",">",">=",是比較操做符。咱們能夠將操做符組合起來使用。
spa

    如:查詢10-20歲的用戶 code

db.user.find({"age"{"$gte":10,"$lte":20}})

  查詢2015年10月1日前註冊的用戶
對象

   start = new Date("01/10/2015")
    db.user.find({"registeDate":{"$lt":start}})

對於文檔中鍵值不等於某個特定值得狀況,就要使用另一個條件操做符「$ne」,表示不相等。

 查詢用戶名字不是「liming」的人。

db.user.find({"name":{"$ne":"liming"}})

OR查詢條件

MongoDB中有2中方式進行or查詢:「$in」能夠用來查詢一個鍵得多個值;「$or」能夠在多個鍵中查詢任意給定值。

一個鍵匹配多個值。

db.user.find({"no":{"$in":[1,23,55,66,78]}})

返回與數組中全部條件都不匹配的文檔,使用「$nin」

db.user.find({"no":{"$nin":[1,23,55,66,78]}})

"$or"能夠接受一個包含可能條件的數組做爲參數

db.user.find({"or":[{"no":12},{"age":20}]})
db.user.find({"or":[{"no":{"$in":[1,2,3,4]}},{"age":20}]})

$not

    "$not"是元條件句,能夠用在任何其餘條件之上。

    如取模運算符「$mod」,將會查詢的值除以第一個給定值,若餘數等於第二個給定值則匹配成功。

db.user.find({"no"{"$mod":[5,1]}})

返回結果是no的值是1,6,11,16等。若是要返回2,3,45,等用戶就要使用$not

db.user.find({"no"{"$not":{"$mod":[5,1]}}})

條件語義

對比前面更新修改器和查詢文檔,咱們會發現以「$」開頭的鍵位於在不一樣的位置。再查詢中「$lt」再內層文檔,更新中'$inc"則在外層文檔。

一個鍵能夠有任意多個條件,可是一個鍵不能對應多個更新修改器。

一些「元操做符」也位於外層文檔,如「$and」、「$or」、「$nor」

db.user.find({"$and":[{"x":{"$lt":1}},{"x"4}]})

特定類型查詢

null類型

 db.user.find({"name":null})

若是文檔中存在name鍵爲null得文檔,則會列出該文檔。若是不存在,則列出缺乏這個鍵的全部文檔。

正則表達式

    正則表達式可以靈活有效地匹配字符串。

查詢數組

$all

    若是須要經過多個元素來匹配數組,就要用 "$all"。

    db.food.find({"fruit":{"$all":["a","b"]}})

    若是想要查詢數組特定位置的元素,須要使用key.index語法指定下標。

db.food.find({"fruit.2":"a"})

    數組下標都是從0開始,因此上面的表達式會翻紅數組第3個元素和「a」進行匹配。

$size

    用來查詢特定長度的數組

 db.food.find({"fruit":{"$siez":3}})

$slice

該操做符能夠返回某個鍵匹配的數組元素的一個子元素。

如:須要返回博客前面10條評論

db.blog.findOne({},{"comments":{"$slice":10}})

須要返回博客後面10條評論

db.blog.findOne({},{"comments":{"$slice":-10}})

也能夠指定偏移值以及但願返回的元素數量,來返回元素集合中間位置的某些結果

db.blog.findOne({},{"comments":{"$slice":[30,10]}})


查詢內嵌文檔

2種方法:查詢整個文檔或者只針對其鍵值對進行查詢。


$where 查詢

使用$where能夠在查詢中執行任意的js。這樣就能夠在查詢中幾乎任何事情,爲了安全,應該嚴格限制或是消除$where語句的使用。

$where查詢在速度上要比常規的查詢慢,每一個文檔都有從BSON轉換成js對象,而後經過$where表達式來運行,且$where語句不能使用索引。

遊標

數據庫使用遊標返回find得執行結果,客戶端對遊標得實現一般可以對最終結果進行有效控制。

執行查詢,分配一個局部變量

var cursor = db.collection.find();

若是沒有把結果放在全局變量或者變量中,MongoDB shell回自動迭代,自動顯示若干文檔。

要迭代結果,可使用遊標得next方法,也可使用hasNext來查看遊標中是否還有其餘結果。

while(cursor.hasNext()){
obj = cursor.next();
}

遊標還實現了js得迭代器接口,咱們也可使用forEach再循環中使用。

cursor.forEach(function(x){
print(x.x);
})

調用find時,shell並不當即查詢數據庫,而是等待真正開始要求得到結果時才發送查詢,這樣再執行查詢前能夠給查詢附加額外的選項。幾乎遊標對象的美俄方法都返回遊標自己,這樣就能夠按任意順序組成方法鏈。

再這以前都是構造查詢。執行cursor.hasNext(),查詢被髮到服務器。shell馬上獲取前面100個結果或者4MB數據,這樣下次調用net或者hasNet就不用再鏈接服務器取結果,客戶端用完第一組結果,shell纔會再次聯繫數據庫,使用getMore請求提取更多結果,若是有則返回下一批結果,這個過程會一直持續直到遊標耗盡或者取徹底部結果。

limit、skip、sort

最經常使用得查詢選項就是限制返回結果的數量、忽略必定數量的結果以及排序。這些選項要在查詢被髮送到服務器以前指定。

限定結果數量,只返回10個結果

db.user.find().limit(10)

略過結果,忽略前面5個匹配的文檔,返回剩下的文檔

db.user.find().skip(5)

sort接受一個對象做爲參數,這個對象是一組鍵值對,鍵對應文檔的鍵名,值表明排序方向,1表明升序,-1表明降序,若是指定多個鍵則安裝指定順序逐個排列。

db.user.find().sort({"userName":1,"age":-1})

能夠組合使用,針對分頁效果大大的好

如搜索MP3,每頁返回50個記錄,價格按照高到低排序

db.shop.find({"name":"mp3"}).limit(50).sort({"price":-1})

下一頁查看更多

db.shop.find({"name":"mp3"}).limit(50).skip(50).sort({"price":-1})

避免使用skip略過大量結果

到時候再開一篇寫

高級查詢

遊標生命週期

在服務端,遊標消耗內存和其餘資源。遊標遍歷盡告終果之後,或者客戶端發來消息要終止,數據庫將會釋放這些資源。釋放的資源會被數據庫另用,因此要保證儘快釋放遊標。

特殊狀況遊標終止,隨後會被自動清理。

遊標完成匹配結果迭代,會清除自身。

客戶端遊標不在做用域,驅動程序會向服務端發送特別消息讓其銷燬。

遊標10分鐘內沒有使用也會自動銷燬。

相關文章
相關標籤/搜索