nodejs操作mongodb之七(mongoose聚合函數的使用)

一、使用聚合函數多表查詢和mongodb類似的

  • 1、定義schema

    const mongoose = require('./db');
    
    const OrderSchema = mongoose.Schema({
        order_id: String,
        uid: Number,
        trade_no: String,
        all_price: Number,
        all_num: Number,
    })
    
    module.exports = mongoose.model('Order', OrderSchema, 'order');
    
  • 2、查詢數據

    const OrderModel = require('./model/order');
    
    OrderModel.aggregate([
        {
            $lookup: {
                from: 'order_item', // 關聯到的表
                localField: 'order_id', // order表的字段
                foreignField: 'order_id', // order_item表的字段
                as: 'item' // 定義返回數據的字段
            }
        },
        {
            $match:{"all_price":{$gte:90}}
        }
        // ...繼續寫別的聚合函數
    ], (err, docs) => {
        if (err) {
            console.log('查詢錯誤');
        } else {
            console.log(JSON.stringify(docs));
        }
    })
    

二、從order_item數據表查詢到order表的數據

  • 1、方式一(比較複雜的方式)

    var mongoose=require('./db.js');
    
    var OrderItemSchema=mongoose.Schema({
        order_id:String,
        title:String,
        price:Number,   
        num:Number    
    })
    module.exports=mongoose.model('OrderItem',OrderItemSchema,'order_item');
    
    // 先根據order_item的id去查找到當前的order_item數據,再根據order_id字段去order表查詢數據
    OrderItemModel.findOne({ "_id": "5b743da92c327f8d1b360546" }, function (err, docs) {
        var order_item = JSON.parse(JSON.stringify(docs));
        var order_id = order_item.order_id;
        OrderModel.find({ "order_id": order_id }, function (err, order) {
            order_item[0].order_info = order[0];
            console.log(order_item)
        })
    })
    
  • 2、方式二(使用聚合函數)

    const OrderModel = require('./model/order');
    const OrderItemModel = require('./model/order_item');
    const mongoose = require('mongoose');
    
    // 從order_item查詢到order表
    OrderItemModel.aggregate([
        // 使用多表的關聯查詢從order_item查詢到order
        {
            $lookup: {
                from: 'order',
                localField: 'order_id',
                foreignField: 'order_id',
                as: 'order_info'
            }
        },
        // 查詢到的數據根據order表的id過濾
        {
            $match:{_id: mongoose.Types.ObjectId('5e0fd4bb08ad70786fd8ac87')}
        }
    ], (err, docs) => {
        if (err) {
            console.log('查詢錯誤');
        } else {
            console.log(JSON.stringify(docs));
        }
    })
    

二、在mongoose中創建一對多的關聯關係的schema

上面的方式僅僅是比較笨的方式自己手動的關聯到關聯數據表的字段。下面介紹使用mongoose.Types.ObjectId的方式去關聯別的表。以案例:

  • 1、老師與學生的關係創建兩個表(主要功能有)

    • 一個班級可以有多個學生
    • 通過班級查詢到全部的學生
    • 通過學生查詢到其所在班級
  • 2、創建班級的schema

    const mongoose = require('./db');
    
    const ClasssSchema = new mongoose.Schema({
      name: {
        type: String,
        require: [true, '此項爲必填內容'],
      },
      // 定義班級下面的學生,因爲一個班級可以是多個學生,所以可以定義爲數組
      students: [
        {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'student',
        }
      ]
    });
    module.exports = mongoose.model('Classs', ClasssSchema, 'classs');
    
  • 3、定義學生的schema

    const mongoose = require('./db');
    
    const StudentSchema = new mongoose.Schema({
      name: {
        type: String,
        require: [true, '此項爲必填內容'],
      },
      age: Number,
    });
    
    module.exports = mongoose.model('Student', StudentSchema, 'student');
    
  • 4、添加學生與班級數據

    const ClasssModel = require('./model/classs');
    const StudentModel = require('./model/student');
    
    // 多次添加學生
    const student = new StudentModel({
      name: '馬六',
      age: 35,
    });
    student.save();
    
    // 添加班級
    const cls = new ClasssModel({
      name: "初中一班",
      students: [
        "5e129534c02d70632fd168dc", // id直接去數據庫查看複製進去的
        "5e1297c02069166b52e34ee4"
      ]
    });
    cls.save();
    
  • 5、通過班級查詢到全部的學生信息

    ClasssModel.aggregate([
      {
        $lookup: {
          from: 'student', // 關聯到學生表
          localField: 'students', // 班級表中關聯的字段
          foreignField: '_id', // 學生表中被關聯的id
          as: 'students',
        }
      }
    ], (err, docs) => {
      if (err) {
        console.log('查詢錯誤', err);
        return
      }
      console.log(JSON.stringify(docs));
    })
    
  • 6、通過學生查詢其所在的班級

    StudentModel.aggregate([
      {
        $lookup: {
          from: 'classs', // 關聯到班級表
          localField: '_id', // 學生的id
          foreignField: 'students', // 關聯到班級表中的字段
          as: 'cls',
        }
      },
      {
        $project: {
          "name": 1,
          "age": 1,
          "cls.name": 1
        }
      }
    ], (err, docs) => {
      if (err) {
        console.log('查詢錯誤', err);
        return
      }
      console.log(JSON.stringify(docs));
    })
    

    在這裏插入圖片描述

三、使用聚合函數進行三表聯合查詢

  • 1、三張表分別爲

    • 用戶表(一個用戶可能有多篇文章)
    • 文章表(一篇文章只能有一個作者,但是可以有多分類)
    • 文章分類表
  • 2、定義三個schema

    // category.js
    const mongoose = require('./db');
    
    const CategorySchema = new mongoose.Schema({
      title: String,
    })
    
    module.exports = mongoose.model('Category', CategorySchema, 'category');
    
    // user.js
    var mongoose = require('./db.js');
    
    var UserSchema = new mongoose.Schema({
      name: String,
      age: Number,
      mobile: Number,
      status: {
        type: Number,
        default: 1
      }
    });
    
    module.exports = mongoose.model('User', UserSchema, 'user');
    
    // article.js
    const mongoose = require('./db');
    
    const ArticleSchema = new mongoose.Schema({
      title: String,
      category: [
        {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'category',
        }
      ],
      author: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'author',
      },
      description: String,
      content: String,
    });
    
    module.exports = mongoose.model('Article', ArticleSchema, 'article');
    
  • 3、創建數據

    const CategoryModel = require('./model/category');
    const UserModel = require('./model/user');
    const ArticleModel = require('./model/article');
    
    // 添加用戶
    const user = new UserModel({
      name: '李四',
      age: 20,
      mobile: 120,
    });
    user.save();
    
    //添加分類
    const category1 = new CategoryModel({
      title: 'nodejs',
    });
    const category2 = new CategoryModel({
      title: 'python',
    });
    const category3 = new CategoryModel({
      title: 'nestjs',
    });
    category1.save();
    category2.save();
    category3.save();
    
    // 文章一
    const article1 = new ArticleModel({
      title: 'nest開發',
      category: [
        '5e12a06bad979e89f8976851', // 從數據庫中複製過來的
        '5e129fd242616287b39dc55c', // 從數據庫中複製過來的
      ],
      author: '5e129f6bdc449e8610bdc1f8', // 從數據庫中複製過來的
      description: 'nestjs連接mongodb',
      content: '省去1000個字',
    })
    
    article1.save();
    // 文章二
    const article2 = new ArticleModel({
      title: 'python開發',
      category: [
        '5e129fd242616287b39dc55d', // 從數據庫中複製過來的
      ],
      author: '5e129f7678a95b8648ebb471', // 從數據庫中複製過來的
      description: 'python基礎開始',
      content: '省去1000個字',
    })
    
    article2.save();
    
  • 4、文章表查詢數據

    // 根據文章表查詢到文章、分類、作者
    ArticleModel.aggregate([
      {
        $lookup: {
          from: 'category',
          localField: 'category',
          foreignField: '_id',
          as: 'category',
        }
      },
      {
        $lookup: {
          from: 'user',
          localField: 'author',
          foreignField: '_id',
          as: 'user',
        }
      },
    ], (err, docs) => {
      if (err) {
        console.log('查詢錯誤', err);
        return
      }
      console.log(JSON.stringify(docs));
    })
    

在這裏插入圖片描述

  • 5、用戶表查詢到文章

    UserModel.aggregate([
      {
        $lookup: {
          from: 'article',
          localField: '_id',
          foreignField: 'author',
          as: 'article',
        }
      },
    ], (err, docs) => {
      if (err) {
        console.log('查詢錯誤', err)
        return
      }
      console.log(JSON.stringify(docs));
    })
    

    在這裏插入圖片描述

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