天天看點

MongoDB幹貨篇之查詢資料

MongoDB幹貨篇之查詢資料

在開始之前我們應該先準備資料友善示範,這裡我插入的了幾條資料,資料如下:

db.user.insertmany( 

[{ 

name:'jack', 

age:22, 

sex:'man', 

tags:['python','c++','c'], 

grades:[22,33,44,55], 

school:{ 

name:'shida', 

city:'xuzhou' 

},{ 

name:'jhon', 

age:33, 

sex:null, 

tags:['python','java'], 

grades:[66,22,44,88], 

name:'kuangda', 

}, 

name:'xiaoming', 

)  

find( , )

其中 query 表示查找的條件,相當于 mysql 中 where 子句, projection 列出你想要查找的資料,格式為 db.collection.find(find(<query filter>, <projection>))

執行個體:

下面不帶參數的查找,将會查找出所有的結果

 db.find().pretty(); 

    //輸出結果 

{                                                      

        "_id" : objectid("59056f81299fe049404b2899"),  

        "name" : "jack",                               

        "age" : 22,                                    

        "tags" : [                                     

                "python",                              

                "c++",                                 

                "c"                                    

        ],                                             

        "grades" : [                                   

                22,                                    

                33,                                    

                44,                                    

                55                                     

        "school" : {                                   

                "name" : "shida",                      

                "city" : "xuzhou"                      

        }                                              

}  

下面找出滿足 name 為 jack 的資料,并且隻輸出 name , age ,這裡的 _id 是預設輸出的,如果不想輸出将将它設定為 0 ,想要輸出那個字段将它設定為1

db.user.find({name:'jack'},{name:1,age:1}) 

//輸出結果 

{ "_id" : objectid("59056f81299fe049404b2899"), "name" : "jack", "age" : 22 } 

db.user.find({name:'jack'},{name:1,age:1,_id:0}) 

{"name" : "jack", "age" : 22 }  

**注意這裡的一個 projection 不能 同時 指定包括和排除字段,除了排除 _id 字段。 在 顯式包括 字段的映射中, _id 字段是唯一一個您可以 顯式排除 的。

查詢内嵌文檔

上述例子中插入的 school 資料就表示内嵌文檔

完全比對查詢

完全比對查詢表示 school 中的查詢數組必須和插入的數組完全一樣,順序都必須一樣才能查找出來

db.user.find({name:'jack',school:{name:'shida',city:'xuzhou'}}); 

{ "_id" : objectid("59056f81299fe049404b2899"), "name" : "jack", "age" : 22, "tags" : [ "python", "c++", "c" ],  

"grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } } 

//下面是指定輸出的字段,這裡的school.name表示隻輸出school文檔中name字段,必須加引号 

db.user.find({name:'jack',school:{name:'shida',city:'xuzhou'}},{name:1,age:1,'school.name':1}); 

{ "_id" : objectid("59056f81299fe049404b2899"), "name" : "jack", "age" : 22, "school" : { "name" : "shida" } }  

鍵值對查詢

可以通過鍵值對查詢,不用考慮順序,比如 'school.name':'shida' ,表示查詢學校名字為shida 的資料,這裡的引号是必須要的

db.user.find({'school.name':'shida'},{name:1,school:1}); 

{ "_id" : objectid("59056f81299fe049404b2899"), "name" : "jack", "school" : { "name" : "shida", "city" : "xuzhou" } }  

查詢操作符

下面我們将配合查詢操作符來執行複雜的查詢操作,比如元素查詢、 邏輯查詢 、比較查詢操作。我們使用下面的比較操作符 "$gt" 、 "$gte" 、 "$lt" 、 "$lte" (分别對應 ">" 、 ">=" 、 "<" 、 "<=" )

執行個體

下面查詢年齡在 20-30 之間的資訊

db.user.find({ 

age:{$gt:20,$lt:30}   

}) 

//輸出 

"grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }  

$ne

$ne 表示不相等,例如查詢年齡不等于 22 歲的資訊

db.user.find({age:{$ne:22}}) 

{ "_id" : objectid("59057c16f551d8c9003d31e0"), "name" : "jhon", "age" : 33, "tags" : [ "python", "java" ],  

"grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } }  

slice

$slice 操作符控制查詢傳回的數組中元素的個數。此操作符根據參數 { field: value } 指定鍵名和鍵值選擇出文檔集合,并且該文檔集合中指定 array 鍵将傳回從指定數量的元素。如果 count 的值大于數組中元素的數量,該查詢傳回數組中的所有元素的。

文法: db.collection.find( { field: value }, { array: {$slice: count }}) ;

下面将查詢 grades 中的前兩個數

db.user.find({name:'jack'},{grades:{$slice:2},name:1,age:1,'school.name':1}); 

//輸出,可以看出這裡的grades隻輸出了前面兩個 

{ "_id" : objectid("59057c16f551d8c9003d31df"), "name" : "jack", "age" : 22, "grades" : [ 22, 33 ], "school" : { "name" : "shida" } }  

下面将輸出後3個資料

db.user.find({name:'jhon'},{grades:{$slice:-3},name:1}); 

{ "_id" : objectid("59057c16f551d8c9003d31e0"), "name" : "jhon", "grades" : [ 22, 44, 88 ] }  

下面介紹指定一個數組作為參數。數組參數使用 [ skip , limit ] 格式,其中第一個值表示在數組中跳過的項目數,第二個值表示傳回的項目數。

db.user.find({name:'jack'},{grades:{$slice:[2,2]},name:1});  //這裡将會跳過前面的兩個,直接得到後面的兩個資料 

{ "_id" : objectid("59057c16f551d8c9003d31df"), "name" : "jack", "grades" : [ 44, 55 ] }  

$exists

如果 $exists 的值為 true ,選擇存在該字段的文檔,若值為 false 則選擇不包含該字段的文檔

下面将會查詢不存在sex這一項的資訊

db.user.find({sex:{$exists:false}}) 

//結果 

{ "_id" : objectid("59058460fe58ed1089f2a5cd"), "name" : "xiaoming", "age" : 33, "tags" : [ "python", "java" ],  

"grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } } 

db.user.find({sex:{$exists:true}}); 

{ "_id" : objectid("59058460fe58ed1089f2a5cb"), "name" : "jack", "age" : 22, "sex" : "man", "tags" : [ "python", "c++", "c" ],  

{ "_id" : objectid("59058460fe58ed1089f2a5cc"), "name" : "jhon", "age" : 33, "sex" : null, "tags" : [ "python", "java" ],  

$or

執行邏輯 or 運算,指定一個至少包含兩個表達式的數組,選擇出至少滿足數組中一條表達式的文檔。

文法: { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionn> } ] }

下面将要查找 age 等于 22 或者 age 等于 33 的值

db.user.find({$or:[{age:22},{age:33}]}) 

下面将會查找出年齡為22或者33并且姓名為 jack 的人的資訊

db.user.find({name:'jack',$or:[{age:33},{age:22}]}) 

$and

指定一個至少包含兩個表達式的數組,選擇出滿足該數組中所有表達式的文檔。 $and 操作符使用短路操作,若第一個表達式的值為“ false ”,餘下的表達式将不會執行。

文法: { $and: [ { <expression1> }, { <expression2> } , ... , { <expressionn> } ] }

下面将會查找年齡在 20-30 之間的資訊,對于下面使用逗号分隔符的表達式清單, mongodb會提供一個隐式的 $and 操作:

db.user.find({$and:[{age:{$gt:20}},{age:{$lt:30}}]}) 

//上述語句相當于db.user.find({age:{$gt:20},age:{$lt:30}}) 

$in

比對鍵值等于指定數組中任意值的文檔。類似 sql 中 in ,隻要比對一個 value 就會輸出

文法: { field: { $in: [<value1>, <value2>, ... <valuen> ] } }

下面将會查找grades中存在22,33之間的任意一個數的資訊

 db.user.find({grades:{$in:[22,33]}}) 

 //輸出 

$nin

比對鍵不存在或者鍵值不等于指定數組的任意值的文檔。類似 sql 中 not in (sql中字段不存在使用會有文法錯誤).

查詢出 grades 中不存在100或者44的文檔

db.user.find({grades:{$nin:[100,44]}}) 

$not

執行邏輯 not 運算,選擇出不能比對表達式的文檔 ,包括沒有指定鍵的文檔。 $not 操作符不能獨立使用,必須跟其他操作一起使用

文法:{ field: { $not: { } } }

查詢年齡不大于30的資訊

db.user.find({age:{$not:{$gt:30}}}) 

本文作者:chenjiabing

來源:51cto