1. 程式人生 > >mongodb學習記錄之一:基礎查詢

mongodb學習記錄之一:基礎查詢

最近在學習mongodb,在學習的過程中,記錄一下部落格,以備以後檢視。

今天先記錄一下find查詢。

在學習之前先往資料庫中插入一定量的資料,這裡我使用迴圈,插入了4096條資料,格式如下:

{
	"name":"李明",
	"sex":"男",
	"score":{
		"math":87,
		"english":65,
		"chinese":78
	}	
}


基礎查詢:

指定查詢條件

空的查詢條件會匹配全部的文件,例如:

>db.students.find()

會將所有的文件都查詢出來。

如果我們想按照條件進行查詢,指定鍵值對即可。整數匹配整數,布林型別匹配布林型別。

例如,我們要查詢所有女生的資訊,則:

>db.students.find({"sex":"女"})	

指定返回的鍵

以上的查詢,將返回文件中所有的鍵,有時候我們並不需要返回所有的鍵,只需要其中的某些鍵,我們可以指定返回的鍵來進行過濾:
>db.students.find({"sex":"女"},{"_id":0,"name":1,"sex":1})

這樣我們就指定了返回的鍵中只含name和sex,_id就不顯示了。 注意:_id這個鍵,如果不指定總是會顯示,如果不想返回_id,則要顯式的指定_id為0,其他鍵不指定則不顯示

條件查詢

查詢條件

查詢不僅能像前面那樣的精確匹配,還能條件匹配。 比如範圍,OR,取反等條件。
條件符 說明
$lt <
$gt >
$lte <=
$gte >=
例子: 1、查詢數學成績大於90的所有女同學
>db.students.find({"score.math":{"$gt":85},"sex":"女"});
2、查詢英語成績在90-94的男同學
>db.students.find({"score.english":{"$gt":90,"$lt":94},"sex":"男"})

OR查詢

mongoDB中有兩種OR查詢:$in和$or

$in用於一個鍵的不同值

$or用於不同鍵的組合

例子: 1、查詢數學成績是90或者95的女生
>db.students.find({"score.math":{"$in":[90,95]},"sex":"女"})
2、查詢數學成績或語文成績滿分的同學
>db.students.find({"$or":[{"score.math":100},{"score.english":100},{"score.chinese":100}]})

$not

$not是元條件句,即可用在任何其他條件之上。 1、查詢語文成績不大於55的學生
>db.students.find({"score.chinese":{"$not":{"$gt":55}}})

其實$not的更強大之處是配合正則。正則以後會慢慢學習。

特定型別的查詢

null查詢

null很奇怪,不僅僅會匹配本身,還能匹配“不存在”的,即可以匹配一個鍵值為null的文件,也可以匹配不存在這個鍵的文件
例如,下面一個例子:
mongo中文件結構如下:
{ "_id" : 2 }
{ "_id" : 3 }
{ "_id" : 6, "name" : 12 }
{ "_id" : 7, "name" : 14 }
{ "_id" : 8, "name" : 16 }
{ "_id" : 9, "name" : 18 }
{ "_id" : 0, "name" : "SaRan" }
{ "_id" : 1, "name" : "SaRan" }
{ "_id" : 5, "book" : "war", "name" : 10 }
{ "_id" : 4, "clazz" : null, "name" : "coolcao" }
{ "_id" : 11, "name" : "good", "clazz" : "class4" }

想要查詢clazz為null的記錄,即_id為4的文件,
>db.person.find({"clazz":null})
查詢出來結果如下,由此看來,null會匹配本身是空值的文件,還能匹配不存在該鍵的文件
{ "_id" : 2 }
{ "_id" : 3 }
{ "_id" : 6, "name" : 12 }
{ "_id" : 7, "name" : 14 }
{ "_id" : 8, "name" : 16 }
{ "_id" : 9, "name" : 18 }
{ "_id" : 0, "name" : "SaRan" }
{ "_id" : 1, "name" : "SaRan" }
{ "_id" : 5, "book" : "war", "name" : 10 }
{ "_id" : 4, "clazz" : null, "name" : "coolcao" }

如果就想只查詢出clazz為null的文件,不存在clazz鍵的不列出來咋辦?使用$exists
>db.person.find({"clazz":{"$in":[null],"$exists":true}})
因為mongo中沒有等於($eq),所以只能使用$in來達到同樣的效果了

正則表示式

正則表示式可以靈活的匹配字串,mongo的find可以支援正則表示式來查詢

查詢所有姓“張”的同學

>db.students.find({"name":{"$regex":"張.+"}})
或
>db.students.find({"name":/張.+/})

這兩種形式是等價的,只不過是用了兩種不同的表達方式而已。

在第一種方式中,更靈活,可以新增可選的引數$options

例如,查詢的姓名中不區分大小寫,則可以如下面:

>db.students.find({"name":{"$regex":"tom","$options":"i"}})
既可以查詢到tom,也可以查詢到Tom,tOm,TOM等等

$options的可選值:

  • i 忽略大小寫
  • m 多行查詢。如果內容裡面不存在換行符號(例如\n)或者構造上沒有(start/end),則該選項沒有任何效果
  • x 空白字元除了被轉義的字元類中的以外完全被忽略,在未轉義的字元類之外的#以及下一個換行符之間的所有字元,包括兩個頭,也都被忽略。
  • s 圓點元字元(.)匹配所有字元,包括換行符

查詢陣列

陣列大多數情況下可以這麼理解:每一個元素都是整個鍵的值

例如,有一個水果的集合,結構如下:


{ "_id" : 1, "fruit" : [  "apple",  "pear",  "banana" ] }
{ "_id" : 3, "fruit" : [  "pear",  "cheey",  "banana" ] }
{ "_id" : 2, "fruit" : [  "apple",  "orange",  "banana",  "pear",  "cheey" ] }
看下面的查詢:
>db.food.find({"fruit":"apple"})

匹配的結果:
{ "_id" : 1, "fruit" : [  "apple",  "pear",  "banana" ] }
{ "_id" : 2, "fruit" : [  "apple",  "orange",  "banana",  "pear",  "cheey" ] }

如果我們要通過多個元素匹配,那麼應該用$all

$all

例如,我們要查詢含有apple和orange的文件:
>db.food.find({"fruit":{"$all":["apple","orange"]}})

如果要精確匹配,就要使用整個陣列了
>db.food.find({"fruit":["apple","banana"]})

上面的語句能“精確”匹配:
{ "_id" : ObjectId("532c409e38c77537a4a525bc"), "fruit" : [  "apple",  "banana" ] }

$size

$size可以查詢指定長度的陣列
>db.food.find({"fruit":{"$size":3}})

上面的例子是查詢food中fruit有3個值的文件

$size並不能與其他查詢子句組合(比如$gt),但是這種查詢可以通過在文件中新增"size"鍵的方式來實現,這樣每一次指定陣列新增元素的時候,同時增加"size"的值。原來這樣的更新:

>db.food.update({"$push":{"fruit":"strawberry"}})
就會變成下面這樣:
>db.food.update({"$push":{"fruit":"strawberry"},"$inc":{"size":1}})

增加的操作非常快,對效能的影響微乎其微。這樣後,就可以像下面這樣查詢了:
>db.food.find({"size":{"$gt":3}})