mongodb聯表查詢

數據庫表

表一: 數據記錄表

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var DocViewSchema = new Schema({
    realName: String, //真實姓名
    userName: String, //OA帳號
    count: Number, //文檔統計
    docName: String, //文檔項目名稱
    docType: String, //文檔項目類型
    orgPath: String, //所屬部門的組織路徑
    orgGroup: String, //所屬事業羣
    orgName: String //所屬小組
    time: String,
});

module.exports = mongoose.model('Doc_view', DocViewSchema);

表二:文檔主表

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;
var docsSchema = new Schema({
    docType:String, //文檔類型
    user_name: String, //系統用戶
    realName: String, //用戶中文姓名
    description: String, // 文檔描述
    gitUrl:String,//操做的文檔源遠程地址
    displayName: String, //文檔展現名
    name:String,//文檔名稱
    logo:String,
    owner:String,//文檔建立人
    developer:Array, //開發者
    realName: String,//真實姓名
    toTop:Date,//是否置頂
    dest: String, //vuepress類型文檔的輸出目錄
    docKey: String, //約束文檔爲public(公開)、private(私有)類型的關鍵字
    privateMember: Array, //存儲私有文檔可查看的人員範圍
    createTime: {
        type: Date,
        default: Date.now
    },
    opendFiles:Array,
    orgName: String, //所屬部門
    orgPath: String, //所屬部門的組織路徑
    orgGroup: String, //所屬事業羣
    docCollection: Array,
    newGit: Boolean //標識是不是在系統上構建的新項目
});
module.exports = mongoose.model('docs', docsSchema);

表數據

表一: 展現數據

{
    "_id" : ObjectId("603678000f6ec514b4b8d02f"),
    "__v" : 0,
    "time" : "2021-02-24",
    "docName" : "abgFeedback",
    "userName" : "zhangsan",
    "orgPath" : "******",
    "orgGroup" : "*****",
    "orgName" : "****",
    "realName" : "張三",
    "count" : 10
}

/* 42 */
{
    "_id" : ObjectId("603678000f6ec514b4b8d030"),
    "__v" : 0,
    "time" : "2021-02-24",
    "docName" : "bookgit",
    "userName" : "liuniu",
    "orgPath" : "******",
    "orgGroup" : "*****",
    "orgName" : "****",
    "realName" : "劉牛",
    "count" : 1
}

/* 43 */
{
    "_id" : ObjectId("603678000f6ec514b4b8d031"),
    "__v" : 0,
    "time" : "2021-02-24",
    "docName" : "testtestdocs",
    "userName" : "lisi",
    "orgPath" : "******",
    "orgGroup" : "*****",
    "orgName" : "****",
    "realName" : "李四",
    "count" : 1
}

/* 44 */
{
    "_id" : ObjectId("6037c9800f6ec514b4b8d03c"),
    "__v" : 0,
    "time" : "2021-02-25",
    "docName" : "abgFeedback",
    "userName" : "zhangsan",
    "orgPath" : "******",
    "orgGroup" : "*****",
    "orgName" : "****",
    "realName" : "張三",
    "count" : 10
}

表二:文檔數據

/* 45 */
{
    "_id" : ObjectId("5f6da851a18a783210da7a16"),
    "docType" : "vuepress",
    "name" : "abgFeedback",
    "gitUrl" : "*****/abgFeedback.git",
    "description" : "問題反饋收集問題",
    "owner" : "zhangsan",
    "orgGroup" : "*****",
    "orgName" : "*****",
    "orgPath" : "****",
    "logo" : "https://img.58cdn.com.cn/escstatic/fecar/pmuse/58doc/58logo.jpeg",
    "newGit" : false,
    "toTop" : ISODate("2020-11-20T02:41:33.742Z"),
    "realName" : "龔成輝",
    "dest" : "abgFeedback",
    "opendFiles" : [],
    "createTime" : ISODate("2020-09-25T08:20:33.373Z"),
    "developer" : [],
    "__v" : 0,
    "docCollection" : [],
    "docKey" : "private",
    "privateMember" : ["lisi"]
}

聯表查詢

db.getCollection('doc_views').aggregate([
    {
        $match: {
            time: {
                $gte: "2020-03-29",
                $lte: "2021-03-29"
            }
        }
    },
    {
        $group: {
            _id: {
                "name": '$docName'
            },
            total: {
                $sum: "$count"
            }
        }
    },
    {
        $lookup: {
            from: "docs",
            localField: "_id.name",
            foreignField: "name",
            as: "child"
        }
    },
   {
       $project: {
           "child._id": false,
           "child.gitUrl": false,
           "child.description": false,
           "child.orgGroup": false,
           "child.orgPath": false,
           "child.newGit": false,
           "child.toTop": false,
           "child.docCollection": false,
           "child.opendFiles": false,
           "child.createTime": false,
           "child.logo": false,
           "child.orgName": false,
           "child.owner": false,
           "child.realName": false,
           "child.__v": false,
           "child.privateMember": false,
           "child.developer": false,
           "child.name": false
      }
    },
])
  1. $match 聚合匹配條件 這塊是以doc_views表time字段匹配前端傳入的起始時間和截止時間段的全部數據
  2. $group 按某些指定的表達式對文檔進行分組,而後將每一個不一樣的分組的文檔輸出到下一階段。輸出文檔包含一個_id字段,其中包含按關鍵字區分的組前端

    1. 這裏以文檔名稱docName爲關鍵字進行分組統計
    2. 同時給docName定義了一個name的別名 幷包裝到_id的對象下面
    3. 把全部當前時間段的同名文檔進行合併並累計count字段輸出total總數
  3. $lookup 關聯查詢vue

    參數 賦值 說明
    from "docs" 須要關聯查詢的表 此處查詢的事主表docs
    localField "_id.name" 匹配查詢數據的表的文檔名稱字段傳參「_id.name」的緣由是:aggregate管道模式數組上一個參數是下一個參數的入參 當前表文檔名稱關鍵字已經被定義到_id對象裏面了
    foreignField "name" 匹配要聯表的文檔名稱關鍵字 即docs表文檔 名稱關鍵字
    as "child" 把當前匹配到的數據輸出到as定義的別名 child裏面 child是一個數組

    注意:以摸一個關鍵字 如:文檔名稱 來聚合數據是 首先聚合出來的數據每一個關鍵字只能有一條數據 不然聯表時沒法匹配出關鍵字對應的主表數據git

  4. $project 可指定顯示或者忽略聯表裏面的某些字段 如上所述 false表示不顯示 true表示顯示

返回結果

//忽略字段的查詢結果
[
  /* 22 */
  {
      "_id" : {
          "name" : "ces1234"
      },
      "total" : 5,
      "child" : [ 
          {
              "docType" : "gitbook",
              "docKey" : "private"
          }
      ]
  },

  /* 23 */
  {
      "_id" : {
          "name" : "abgFeedback"
      },
      "total" : 43,
      "child" : [ 
          {
              "docType" : "vuepress",
              "dest" : "abgFeedback",
              "docKey" : "private"
          }
      ]
  }
]
//不忽略字段的返回結果
[
  /* 22 */
  {
      "_id" : {
          "name" : "ces1234"
      },
      "total" : 5,
      "child" : [ 
          {
              "_id" : ObjectId("5da19272f76a861008c468ff"),
              "docType" : "gitbook",
              "name" : "ces1234",
              "gitUrl" : "***/docs/ces1234.git",
              "description" : "APP前端組業務文檔",
              "owner" : "zhangsan",
              "opendFiles" : [],
              "createTime" : ISODate("2019-10-12T08:44:34.986Z"),
              "developer" : [ "lisi" ],
              "__v" : 0,
              "orgPath" : "****",
              "orgName" : "****",
              "orgGroup" : "****",
              "toTop" : ISODate("2020-06-12T02:09:20.255Z"),
              "logo" : "https://img.58cdn.com.cn/escstatic/fecar/pmuse/58doc/58logo.jpeg",
              "docCollection" : [],
              "docKey" : "private",
              "privateMember" : [],
              "realName" : "龔成輝",
              "displayName" : "測試項目"
          }
      ]
  },

  /* 23 */
  {
      "_id" : {
          "name" : "abgFeedback"
      },
      "total" : 43,
      "child" : [ 
          {
              "_id" : ObjectId("5f6da851a18a783210da7a16"),
              "docType" : "vuepress",
              "name" : "abgFeedback",
              "gitUrl" : "****/docs/abgFeedback.git",
              "description" : "問題反饋收集問題",
              "owner" : "gongchenghui",
              "orgGroup" : "****",
              "orgName" : "****",
              "orgPath" : "****",
              "logo" : "https://img.58cdn.com.cn/escstatic/fecar/pmuse/58doc/58logo.jpeg",
              "newGit" : false,
              "toTop" : ISODate("2020-11-20T02:41:33.742Z"),
              "realName" : "龔成輝",
              "dest" : "abgFeedback",
              "opendFiles" : [],
              "createTime" : ISODate("2020-09-25T08:20:33.373Z"),
              "developer" : [],
              "__v" : 0,
              "docCollection" : [],
              "docKey" : "private",
              "privateMember" : [ 
                  "wangwu"
              ],
              "displayName" : "前端問題反饋"
          }
      ]
  }
]