Mongodb查詢學習

這才寫了第二篇文章,文本拙劣,單純記錄一下工作上遇到的問題和解決的方法,如果更好的方法,希望大家在留言中回覆一下。

mongodb查詢數據時使用JavaScript語言,這大大增加了查詢的自由度。mongodb官網提供的Aggregate查詢方法,實現了類似sql鏈接查詢的功能,可以在查詢的時候過濾掉不需要的數據,可以進行分類統計。

集合管道查詢是爲了實現類似這種操作:先查到一張表裏的數據,然後根據這種表的數據去查詢另一張表,哈!其實就是連接查詢,不過管道的底層是在mongodb查詢引擎中自行實現的,一次查詢=>結果,後端查詢是通過tcp連接去數據庫裏查詢,所以時間上會比較浪費,如果使用Aggregate的話,則是一次查詢,然後得到結果。

這裏簡單介紹一下Aggregate的參數。
先拿段查詢代碼來看一下吧!

db.lines.aggregate([
  { // $match字面意思就能理解,是查詢條件,或者是過濾條件。
    "$match": {
      "hospital": "58cf877bcfff701fc6d877f8",
      "patient": {
        "$exists": true,
        "$ne": null
      }
    }
  },
  { // $lookup就是需要連接集合
    "$lookup": {
      "from": "patients",       // from是鏈接的表名
      "localField": "patient",  // localField是主集合上關聯到鏈接集合的鍵名
      "foreignField": "_id",    // foreignField是與上邊鍵名對應在關聯集合中的鍵名
      "as": "patient"           // as 是在後續查詢時關聯表數據的別名
    }
  },
  {   // $project 過濾掉想要的數據
    "$project": {   
      "date" : 1,
      "patient": {
        "$arrayElemAt": [ "$patient", 0 ]  // 聚合查詢返回的結果是數組,所以需要用$arrayElemAt命令,取到想要的行數,這裏取得是第0行。
                                           // 這裏的$patient 中的patient就是lookup關聯集合中as取的名字。$字符是取到上一管道中對應屬性名稱的值
      },
      "updatedAt": 1,
  },
  {
    "$match": {   // 在管道中可以隨時插入$match來過濾掉需要的數據
      "schedule": "running",
      "customerSchedule": "594a3d07ae86aab90778cdf0"
    }
  },
  {
    "$group": {   //$group 分類數據,統計數據等功能
      "_id":{ month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } }, 
      // 這裏一定要把分類的標準放到 _id 裏面,$month,$dayOfMonth,$year可以取到年月日,根據年月日來區分數據
      "count": {
        "$sum": 1   //$sum爲累加,可以自行填寫權值。這裏權值爲1,作用是統計個數。
      },
      "data" : {
        "$push" : "$patient" // $push命令把當前分組的數據集合進行記錄,可以自行拼接
                             // 比如 "$push" : {name: "$name",age: "$age"}
      }
    }
  }
])

因爲mongodb使用的是JavaScript語言作爲查詢語言,所以在查詢時同樣支持js的語法規則。
有一種場景爲,想根據查詢的結果去修改數據庫中的值,在數據庫中可以這麼寫

db.schedules.aggregate([
{
    $match:{
        custoer:{$exists: false}
        }
},
{
    $lookup:{
        from:'lines',
        localField:'line',
        foreignField:'_id',
        as:'lineObj'
    }
},
{
     $project:{
        _id:1,
        lineObj:{$arrayElemAt:['$lineObj',0]}
     }
 },
 {
     $project:{
        _id:1,
        customer:'$lineObj.customer'
     }
 },
 {
     $match:{
        customer:{$exists: true}
     }
  }
]).forEach(function(x){
printjson("db.schedules.update({_id:ObjectId('"+x._id+"')},{$set:{'customer':ObjectId('"+x.customer+"')}})")
})

可以先把需要的數據查詢出來們這裏應用上邊所述的Aggregate查詢,是因爲所需要的數據不在同一張表中。重點在下邊:因爲查詢的結果爲數組,所以可以直接使用forEach方法,執行函數的參數就是每行數據的值,這裏使用printjson來打印生成的腳本。執行如上命令後生成的腳本帶有雙引號,去除後可以拿到mongodb引擎中去執行。

腹中墨水有限,只能寫到這了,有雞蛋儘管扔哈,建議最好啦,望相授。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章