MongoDB入門6——查詢(二)

 3.查詢中null的處理

        null的匹配非常有意思:null不僅僅會匹配到指定鍵的值確實等於null的文檔,並且還會匹配到查詢所制定鍵不存在的文檔。例如,插入下面這三個文檔:

db.users.insert({"name":"Tom","age":20,"job":"Sales"});
db.users.insert({"name":"Sam","age":25,"job":"Manager"});
db.users.insert({"name":"Jim","age":25});
db.users.insert({"name":"Sam","age":25,"job":null});

        現在我們用傳統的方式來匹配job爲null的文檔:

db.users.find({"job":null});

        結果如下:

{ "_id" : ObjectId("4f0714e3edb28db4864be582"), "name" : "Jim", "age" : 25 }
{ "_id" : ObjectId("4f071542edb28db4864be583"), "name" : "Sam", "age" : 25, "job" : null }

        很明顯,不僅將job確實爲null的文檔匹配出來,而且將沒有job這個鍵的文檔匹配出來了。很多時候這並不是我們的本意。有一個$exists操作符可以來解決這個問題。先看代碼:

db.users.find({"job":{"$in":[null],"$exists":true}});

        結果如下:

{ "_id" : ObjectId("4f071542edb28db4864be583"), "name" : "Sam", "age" : 25, "job" : null }

4.正則表達式

        MongoDB使用Perl兼容的正則表達式庫來匹配正則表達式。正則表達式本身非常強大,有專門寫這個的書,我這裏不針對這個,只是簡單的舉個例子。例如,忽略大小寫情況下匹配name爲Tom的文檔:

db.users.find({"name":/tom/i});

5.數組查詢

        數組查詢大的思路:大部分情況下,數組的每個元素都可以是對應鍵的值。這麼說肯定不好理解,舉個例子,插入下面這樣一個文檔:

db.food.insert({"fruit":["apple","banana","peach"]});

        現在執行下面三個查詢,都會將這個文檔匹配出來。

db.food.find({"fruit":"apple"});
db.food.find({"fruit":"banana"});
db.food.find({"fruit":"peach"});

        如果需要匹配fruit鍵的值既有apple又有banana的文檔,可以使用$all匹配符。現在我們假設有下面幾個文檔:

{ "_id" : ObjectId("4f071a10edb28db4864be584"), "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : ObjectId("4f071c5676285076f80ca7c7"), "fruit" : [ "apple", "banana" ] }
{ "_id" : ObjectId("4f071c6076285076f80ca7c8"), "fruit" : [ "apple" ] }
{ "_id" : ObjectId("4f071ce576285076f80ca7c9"), "fruit" : [ "banana", "apple" ] } 

         執行下面的查詢:

db.food.find({"fruit":{"$all":["apple","banana"]}});

        可以匹配到下面的三個文檔:

{ "_id" : ObjectId("4f071a10edb28db4864be584"), "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : ObjectId("4f071c5676285076f80ca7c7"), "fruit" : [ "apple", "banana" ] }
{ "_id" : ObjectId("4f071ce576285076f80ca7c9"), "fruit" : [ "banana", "apple" ] }

        你可能會說,可以採用精確匹配整個數組的方法如下:

db.food.find({"fruit":["apple","banana"]});

        得到的結果只有一個文檔:

{ "_id" : ObjectId("4f071c5676285076f80ca7c7"), "fruit" : [ "apple", "banana" ] }

        不用驚訝,這就是精確匹配,連apple和banana出現的順序都不能調換。這種結果很顯然不是很多時候我們想要的。也是爲什麼引進$all匹配操作符。

        還有一種匹配的語法:可以使用key.index來匹配指定鍵對應值(是數組的情況下)的第index+1個元素值。還是上面水果的那個例子,我們假設要匹配fruit鍵對應值第三個元素爲peach的文檔,我們可以這麼寫:

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

        注意一點,數組下標是從0開始的。

        如果我們需要匹配fruit鍵的值數組元素個數爲3個的文檔,可以使用$size匹配操作符:

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

        這樣也可以將第一個文檔匹配出來。但是特別需要注意,$size匹配符是不能和其他的查詢條件共同使用的。比如你按照下面寫是不會有結果的:

db.food.find({"fruit":{"$gt":{"$size":2}}});

       這是不會匹配出fruit鍵的值數組元素個數大於2的文檔。這樣不會有任何查詢結果的。

 

《MongoDB:The Definitive Guide》

發佈了51 篇原創文章 · 獲贊 9 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章