摘要:上一篇文章指南更新文檔下一篇文章指南特定類型的查詢本章將詳細介紹查詢。查詢條件和就是全部的比較操作符,分別對應和。如果查詢優(yōu)化器可以更高效地處理,那就選擇使用它。注意,查詢優(yōu)化器不會對進行優(yōu)化,這與其他操作符不同。
上一篇文章:MongoDB指南---6、更新文檔
下一篇文章:MongoDB指南---8、特定類型的查詢
本章將詳細介紹查詢。主要會涵蓋以下幾個方面:
使用find或者findOne函數(shù)和查詢文檔對數(shù)據(jù)庫執(zhí)行查詢;
使用$條件查詢實現(xiàn)范圍查詢、數(shù)據(jù)集包含查詢、不等式查詢,以及其他一些查詢;
查詢將會返回一個數(shù)據(jù)庫游標,游標只會在你需要時才將需要的文檔批量返回;
還有很多針對游標執(zhí)行的元操作,包括忽略一定數(shù)量的結(jié)果,或者限定返回結(jié)果的數(shù)量,以及對結(jié)果排序。
4.1 find簡介MongoDB中使用find來進行查詢。查詢就是返回一個集合中文檔的子集,子集合的范圍從0個文檔到整個集合。find的第一個參數(shù)決定了要返回哪些文檔,這個參數(shù)是一個文檔,用于指定查詢條件。
空的查詢文檔(例如{})會匹配集合的全部內(nèi)容。要是不指定查詢文檔,默認就是{}。例如:
> db.c.find()
將批量返回集合c中的所有文檔。
開始向查詢文檔中添加鍵/值對時,就意味著限定了查詢條件。對于絕大多數(shù)類型來說,這種方式很簡單明了。數(shù)值匹配數(shù)值,布爾類型匹配布爾類型,字符串匹配字符串。查詢簡單的類型,只要指定想要查找的值就好了,十分簡單。例如,想要查找"age"值為27的所有文檔,直接將這樣的鍵/值對寫進查詢文檔就好了:
> db.users.find({"age" : 27})
要是想匹配一個字符串,比如值為"joe"的"username"鍵,那么直接將鍵/值對寫在查詢文檔中即可:
> db.users.find({"username" : "joe"})
可以向查詢文檔加入多個鍵/值對,將多個查詢條件組合在一起,這樣的查詢條件會被解釋成“條件1AND條件2AND ... AND條件N”。例如,要想查詢所有用戶名為joe且年齡為27歲的用戶,可以像下面這樣:
> db.users.find({"username" : "joe", "age" : 27})4.1.1 指定需要返回的鍵
有時并不需要將文檔中所有鍵/值對都返回。遇到這種情況,可以通過find(或者findOne)的第二個參數(shù)來指定想要的鍵。這樣做既會節(jié)省傳輸?shù)臄?shù)據(jù)量,又能節(jié)省客戶端解碼文檔的時間和內(nèi)存消耗。
例如,如果只對用戶集合的"username"和"email"鍵感興趣,可以使用如下查詢返回這些鍵:
> db.users.find({}, {"username" : 1, "email" : 1}) { "_id" : ObjectId("4ba0f0dfd22aa494fd523620"), "username" : "joe", "email" : "joe@example.com" }
可以看到,默認情況下"_id"這個鍵總是被返回,即便是沒有指定要返回這個鍵。
也可以用第二個參數(shù)來剔除查詢結(jié)果中的某些鍵/值對。例如,文檔中有很多鍵,但是我們不希望結(jié)果中含有"fatal_weakness"鍵:
> db.users.find({}, {"fatal_weakness" : 0})
使用這種方式,也可以把"_id"鍵剔除掉:
> db.users.find({}, {"username" : 1, "_id" : 0}) { "username" : "joe", }4.1.2 限制
查詢的使用上有些限制。傳遞給數(shù)據(jù)庫的查詢文檔的值必須是常量。(在你自己的代碼里可以是正常的變量。)也就是不能引用文檔中其他鍵的值。例如,要想保持庫存,有"in_stock"(剩余庫存)和"num_sold"(已出售)兩個鍵,想通過下列查詢來比較兩者的值是行不通的:
> db.stock.find({"in_stock" : "this.num_sold"}) // 這樣是行不通的
的確有辦法實現(xiàn)類似的操作(詳見4.4節(jié)),但通常需要略微修改一下文檔結(jié)構(gòu),就能通過普通查詢來完成這樣的操作了,這種方式性能更好。在這個例子中,可以在文檔中使用"initial_stock"(初始庫存)和"in_stock"兩個鍵。這樣,每當有人購買物品,就將"in_stock"減去1。這樣,只需要用一個簡單的查詢就能知道哪種商品已脫銷:
> db.stock.find({"in_stock" : 0})4.2 查詢條件
查詢不僅能像前面說的那樣精確匹配,還能匹配更加復雜的條件,比如范圍、OR子句和取反。
4.2.1 查詢條件"$lt"、"$lte"、"$gt"和"$gte"就是全部的比較操作符,分別對應<、<=、>和>=。可以將其組合起來以便查找一個范圍的值。例如,查詢18~30歲(含)的用戶,就可以像下面這樣:
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
這樣就可以查找到"age"字段大于等于18、小于等于30的所有文檔。
這樣的范圍查詢對日期尤為有用。例如,要查找在2007年1月1日前注冊的人,可以像下面這樣:
> start = new Date("01/01/2007") > db.users.find({"registered" : {"$lt" : start}})
可以對日期進行精確匹配,但是用處不大,因為文檔中的日期是精確到毫秒的。而我們通常是想得到一天、一周或者是一個月的數(shù)據(jù),這樣的話,使用范圍查詢就很有必要了。
對于文檔的鍵值不等于某個特定值的情況,就要使用另外一種條件操作符"$ne"了,它表示“不相等”。若是想要查詢所有名字不為joe的用戶,可以像下面這樣查詢:
> db.users.find({"username" : {"$ne" : "joe"}})
"$ne"能用于所有類型的數(shù)據(jù)。
4.2.2 OR查詢MongoDB中有兩種方式進行OR查詢:"$in"可以用來查詢一個鍵的多個值;"$or"更通用一些,可以在多個鍵中查詢?nèi)我獾慕o定值。
如果一個鍵需要與多個值進行匹配的話,就要用"$in"操作符,再加一個條件數(shù)組。例如,抽獎活動的中獎號碼是725、542和390。要找出全部的中獎文檔的話,可以構(gòu)建如下查詢:
> db.raffle.find({"ticket_no" : {"$in" : [725, 542, 390]}})
"$in"非常靈活,可以指定不同類型的條件和值。例如,在逐步將用戶的ID號遷移成用戶名的過程中,查詢時需要同時匹配ID和用戶名:
> db.users.find({"user_id" : {"$in" : [12345, "joe"]})
這會匹配"user_id"等于12345的文檔,也會匹配"user_id"等于"joe"的文檔。
要是"$in"對應的數(shù)組只有一個值,那么和直接匹配這個值效果一樣。例如,{ticket_no : {$in:[725]}}和{ticket_no : 725}的效果一樣。
與"$in"相對的是"$nin","$nin"將返回與數(shù)組中所有條件都不匹配的文檔。要是想返回所有沒有中獎的人,就可以用如下方法進行查詢:
> db.raffle.find({"ticket_no" : {"$nin" : [725, 542, 390]}})
該查詢會返回所有沒有中獎的人。
"$in"能對單個鍵做OR查詢,但要是想找到"ticket_no"為725或者"winner"為true的文檔該怎么辦呢?對于這種情況,應該使用"$or"。"$or"接受一個包含所有可能條件的數(shù)組作為參數(shù)。上面中獎的例子如果用"$or"改寫將是下面這個樣子:
> db.raffle.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]})
"$or"可以包含其他條件。例如,如果希望匹配到中獎的"ticket_no",或者"winner"鍵的值為true的文檔,就可以這么做:
> db.raffle.find({"$or" : [{"ticket_no" : {"$in" : [725, 542, 390]}}, {"winner" : true}]})
使用普通的AND型查詢時,總是希望盡可能用最少的條件來限定結(jié)果的范圍。OR型查詢正相反:第一個條件應該盡可能匹配更多的文檔,這樣才是最為高效的。
"$or"在任何情況下都會正常工作。如果查詢優(yōu)化器可以更高效地處理"$in",那就選擇使用它。
"$not"是元條件句,即可以用在任何其他條件之上。就拿取模運算符"$mod"來說。"$mod"會將查詢的值除以第一個給定值,若余數(shù)等于第二個給定值則匹配成功:
> db.users.find({"id_num" : {"$mod" : [5, 1]}})
上面的查詢會返回"id_num"值為1、6、11、16等的用戶。但要是想返回"id_num"為2、3、4、5、7、8、9、10、12等的用戶,就要用"$not"了:
> db.users.find({"id_num" : {"$not" : {"$mod" : [5, 1]}}})
"$not"與正則表達式聯(lián)合使用時極為有用,用來查找那些與特定模式不匹配的文檔(4.3.2節(jié)會詳細講述正則表達式的使用)。
4.2.4 條件語義如果比較一下上一章的更新修改器和前面的查詢文檔,會發(fā)現(xiàn)以$開頭的鍵位于在不同的位置。在查詢中,"$lt"在內(nèi)層文檔,而更新中"$inc"則是外層文檔的鍵。基本可以肯定:條件語句是內(nèi)層文檔的鍵,而修改器則是外層文檔的鍵。
可以對一個鍵應用多個條件。例如,要查找年齡為20~30的所有用戶,可以在"age"鍵上使用"$gt"和"$lt":
> db.users.find({"age" : {"$lt" : 30, "$gt" : 20}})
一個鍵可以有任意多個條件,但是一個鍵不能對應多個更新修改器。例如,修改器文檔不能同時含有{"$inc" : {"age" : 1}, "$set" : {age : 40}},因為修改了"age"兩次。但是對于查詢條件句就沒有這種限定。
有一些“元操作符”(meta-operator)也位于外層文檔中,比如"$and"、"$or"和"$nor"。它們的使用形式類似:
> db.users.find({"$and" : [{"x" : {"$lt" : 1}}, {"x" : 4}]})
這個查詢會匹配那些"x"字段的值小于等于1并且等于4的文檔。雖然這兩個條件看起來是矛盾的,但是這是完全有可能的,比如,如果"x"字段的值是這樣一個數(shù)組{"x" : [0, 4]},那么這個文檔就與查詢條件相匹配。注意,查詢優(yōu)化器不會對"$and"進行優(yōu)化,這與其他操作符不同。如果把上面的查詢改成下面這樣,效率會更高:
> db.users.find({"x" : {"$lt" : 1, "$in" : [4]}})
上一篇文章:MongoDB指南---6、更新文檔
下一篇文章:MongoDB指南---8、特定類型的查詢
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44004.html
摘要:上一篇文章指南更新文檔下一篇文章指南特定類型的查詢本章將詳細介紹查詢。查詢條件和就是全部的比較操作符,分別對應和。如果查詢優(yōu)化器可以更高效地處理,那就選擇使用它。注意,查詢優(yōu)化器不會對進行優(yōu)化,這與其他操作符不同。 上一篇文章:MongoDB指南---6、更新文檔下一篇文章:MongoDB指南---8、特定類型的查詢 本章將詳細介紹查詢。主要會涵蓋以下幾個方面: 使用find或者f...
摘要:但有時我們希望返回與查詢條件相匹配的任意一個數(shù)組元素。首先,可以使用要求同時使用查詢條件中的兩個語句與一個數(shù)組元素進行比較。 上一篇文章:MongoDB指南---7、find簡介與查詢條件下一篇文章:MongoDB指南---9、游標與數(shù)據(jù)庫命令 如第2章所述,MongoDB的文檔可以使用多種類型的數(shù)據(jù)。其中有一些在查詢時會有特別的表現(xiàn)。 4.3.1 null null類型的行為有點奇...
摘要:但有時我們希望返回與查詢條件相匹配的任意一個數(shù)組元素。首先,可以使用要求同時使用查詢條件中的兩個語句與一個數(shù)組元素進行比較。 上一篇文章:MongoDB指南---7、find簡介與查詢條件下一篇文章:MongoDB指南---9、游標與數(shù)據(jù)庫命令 如第2章所述,MongoDB的文檔可以使用多種類型的數(shù)據(jù)。其中有一些在查詢時會有特別的表現(xiàn)。 4.3.1 null null類型的行為有點奇...
摘要:可以通過來強制使用某個特定的索引,再次執(zhí)行這個查詢,但是這次使用,作為索引。 上一篇文章:MongoDB指南---9、游標與數(shù)據(jù)庫命令下一篇文章:MongoDB指南---11、使用復合索引、$操作符如何使用索引、索引對象和數(shù)組、索引基數(shù) 本章介紹MongoDB的索引,索引可以用來優(yōu)化查詢,而且在某些特定類型的查詢中,索引是必不可少的。 什么是索引?為什么要用索引? 如何選擇需要建立...
摘要:可以通過來強制使用某個特定的索引,再次執(zhí)行這個查詢,但是這次使用,作為索引。 上一篇文章:MongoDB指南---9、游標與數(shù)據(jù)庫命令下一篇文章:MongoDB指南---11、使用復合索引、$操作符如何使用索引、索引對象和數(shù)組、索引基數(shù) 本章介紹MongoDB的索引,索引可以用來優(yōu)化查詢,而且在某些特定類型的查詢中,索引是必不可少的。 什么是索引?為什么要用索引? 如何選擇需要建立...
閱讀 2562·2021-11-22 12:05
閱讀 3447·2021-10-14 09:42
閱讀 1679·2021-07-28 00:15
閱讀 1986·2019-08-30 11:08
閱讀 1482·2019-08-29 17:31
閱讀 926·2019-08-29 16:42
閱讀 2335·2019-08-26 11:55
閱讀 2112·2019-08-26 11:49