MongoDB乾貨篇之查詢數據

  • 2019 年 12 月 31 日
  • 筆記

文章目錄

  1. 1. MongoDB乾貨篇之查詢
    1. 1.1. 準備工作
    2. 1.2. find()
      1. 1.2.1. 實例:
    3. 1.3. 查詢內嵌文檔
      1. 1.3.1. 完全匹配查詢
      2. 1.3.2. 鍵值對查詢
    4. 1.4. 查詢操作符
      1. 1.4.1. 實例
      2. 1.4.2. $ne
      3. 1.4.3. slice
      4. 1.4.4. $exists
      5. 1.4.5. $or
      6. 1.4.6. $and
      7. 1.4.7. $in
      8. 1.4.8. $nin
      9. 1.4.9. $not
    5. 1.5. 迭代游標的查詢

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],  school:{  name:'kuangda',  city:'xuzhou'  }  },  {  name:'xiaoming',  age:33,  tags:['python','java'],  grades:[66,22,44,88],  school:{  name:'kuangda',  city:'xuzhou'  }  }  ]  )

find()

其中query表示查找的條件,相當於mysqlwhere子句,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"          }  }
  • 下面找出滿足namejack的數據,並且只輸出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}  })  //輸出  { "_id" : ObjectId("59056f81299fe049404b2899"), "name" : "jack", "age" : 22, "tags" : [ "python", "c++", "c" ], "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" ], "grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }  { "_id" : ObjectId("59058460fe58ed1089f2a5cc"), "name" : "jhon", "age" : 33, "sex" : null, "tags" : [ "python", "java" ], "grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } }  

$or

執行邏輯OR運算,指定一個至少包含兩個表達式的數組,選擇出至少滿足數組中一條表達式的文檔。 語法:{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }

  • 下面將要查找age等於22或者age等於33的值
db.user.find({$or:[{age:22},{age:33}]})  //結果  { "_id" : ObjectId("59058460fe58ed1089f2a5cb"), "name" : "jack", "age" : 22, "sex" : "Man", "tags" : [ "python", "c++", "c" ], "grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }  { "_id" : ObjectId("59058460fe58ed1089f2a5cc"), "name" : "jhon", "age" : 33, "sex" : null, "tags" : [ "python", "java" ], "grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } }  { "_id" : ObjectId("59058460fe58ed1089f2a5cd"), "name" : "xiaoming", "age" : 33, "tags" : [ "python", "java" ], "grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } }  
  • 下面將會查找出年齡為22或者33並且姓名為jack的人的信息
db.user.find({name:'jack',$or:[{age:33},{age:22}]})  //結果  { "_id" : ObjectId("59058460fe58ed1089f2a5cb"), "name" : "jack", "age" : 22, "sex" : "Man", "tags" : [ "python", "c++", "c" ], "grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }

$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}})  //結果  { "_id" : ObjectId("59058460fe58ed1089f2a5cb"), "name" : "jack", "age" : 22, "sex" : "Man", "tags" : [ "python", "c++", "c" ], "grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }

$in

匹配鍵值等於指定數組中任意值的文檔。類似sqlin,只要匹配一個value就會輸出 語法:{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }

  • 下面將會查找grades中存在22,33之間的任意一個數的信息
db.user.find({grades:{$in:[22,33]}})     //輸出    { "_id" : ObjectId("59058460fe58ed1089f2a5cb"), "name" : "jack", "age" : 22, "sex" : "Man", "tags" : [ "python", "c++", "c" ], "grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }  { "_id" : ObjectId("59058460fe58ed1089f2a5cc"), "name" : "jhon", "age" : 33, "sex" : null, "tags" : [ "python", "java" ], "grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } }  { "_id" : ObjectId("59058460fe58ed1089f2a5cd"), "name" : "xiaoming", "age" : 33, "tags" : [ "python", "java" ], "grades" : [ 66, 22, 44, 88 ], "school" : { "name" : "kuangda", "city" : "xuzhou" } }

$nin

 匹配鍵不存在或者鍵值不等於指定數組的任意值的文檔。類似sqlnot 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}}})  //輸出  { "_id" : ObjectId("59058460fe58ed1089f2a5cb"), "name" : "jack", "age" : 22, "sex" : "Man", "tags" : [ "python", "c++", "c" ], "grades" : [ 22, 33, 44, 55 ], "school" : { "name" : "shida", "city" : "xuzhou" } }

迭代游標的查詢

學過高級語言的朋友都知道迭代的問題,像java,下面使用迭代的方法查詢

var cursor=db.usr.find();  //這裡使用迭代輸出所有的數據  while(cursor.hasNext())    //這裡的hasNext()是判斷是否下一個中還有可迭代的值,如果沒有返回false  {      printjson(cursor.next());     //這裡的cursor.next是迭代的輸出,printjson是代替print(tojson())  }  print cursor.count()    //輸出其中有多少個數據  cursor.forEach(printjson);   //forEach輸出  var document=cursor.toArray();     //將迭代對象轉換成數組  print document[0];       //以數組的形式輸出