mongodb用mongoose查庫的對象,不能增加屬性修改屬性

node + koa2 + mongodb 寫了一個給前端的接口

如果不是寫這個接口,這輩子都發現不了mongodb裏這個大坑
mongoose 是個ODM(Object Document Mapper),mongodb是nosql數據庫,文檔存儲 mysql,sqlserver,oracle都是關係型數據庫
所以mongodb無法在取到對象增加屬性,必須在追加時候重新用一個對象,或者在schema中添加這個對象的key

  • model.js
// 這裏用來建數據庫表結構相關的
const mongoose = require('mongoose');

mongoose.connect('mongodb://127.0.0.1:27017/zhongtong', {
    useNewUrlParser: true
}); // 連接數據庫

let categorySchema = new mongoose.Schema({
        name: String
    }),
    categoryModel = mongoose.model('category', categorySchema), // 分類
    contentSchema = new mongoose.Schema({
        name: String,
        poster: String,
        source: String,
        addTime: Date,
        checkFirst: Boolean,
        checkSecond: Boolean,
        checkThird: Boolean,
        categoryId: String
    }),
    contentModel = mongoose.model('content', contentSchema), // 內容
    bannerSchema = new mongoose.Schema({
        src: String,
        categoryId: String,
        type: Number
    }),
    bannerModel = mongoose.model('banner', bannerSchema); // 輪播圖banner

module.exports = {
    categoryModel,
    contentModel,
    bannerModel
};

  • index.js
這裏寫前端接口,採用post請求
const router = require('koa-router')(), // 路由
    globalVariable = require('../config/variable'), // 狀態碼
    model = require('../model/model'), // 模型
    categoryModel = model.categoryModel, // 分類
    contentModel = model.contentModel, // 內容
    bannerModel = model.bannerModel, // banner
    VARIABLE = globalVariable.VARIABLE, // 狀態碼
    STATUS = globalVariable.STATUS; // 狀態格式

router.prefix('/zt');

// 首頁接口
router.post('/home', async (ctx, next) => {
    try {
        let category = await categoryModel.find(), // 類型
            categoryId = category.map(value => {
                return value.id;
            }),
            banner = await bannerModel.find(),
            arr = [],
            list = [];

        for (let i = 0; i < categoryId.length; i++) {
            await contentModel
                .find({ categoryId: categoryId[i] })
                .limit(10)
                .then(v => {
                    arr.push(v);
                });
        }

        ctx.body = {
            code: VARIABLE.SUCCESS_CODE,
            msg: VARIABLE.SUCCESS_MSG,
            data: {
                banner: banner,
                category: category,
                contentList: list
            }
        };
    } catch (err) {
        ctx.body = STATUS.ERROR;
    }
});

這樣查出來的接口格式是這樣的

但是對於前端來說,需要的接口是category和content對應起來的,也就是期望想要如下的樣子

其實並不難,就是在category每個對象後面增加一個數組而已,我們可能想就是這樣

  • index.js
let list = []; // 這個就是組成後的數組
for (let i = 0; i < categoryId.length; i++) {
    list[i]['content'] =  arr[i]; // arr就是上面代碼裏的查出content表的內容
}

但是你會發現,直接輸出list永遠都是沒有content屬性的一個數組,但是如果直接list.contegt 就有裏面arr的值,簡直無語。。。

這也就是mongodb的一個問題

  • 第一種解決方法
在category表裏增加一個字段content,但是如果這個讓dba看到了肯定一頓吐槽,這個表結構也太不專業了吧。而且這就是數據庫的冗餘字段啊
  • 第二種解決辦法
// index.js
// 把category裏的數據放到一個新的數組,並且數組裏追加的對象新建一個key
for (let i = 0; i < category.length; i++) {
            /* 
             * 坑!!
             * 如果不是寫這個接口,這輩子都發現不了mongodb裏這個大坑,哼,研究了寶寶好久
             * mongoose 是個ODM(Object Document Mapper),mongodb是nosql數據庫,文檔存儲
             * mysql,sqlserver,oracle都是關係型數據庫,
             * 所以mongodb無法在取到對象增加屬性,必須在追加時候重新用一個對象,或者在schema中添加這個對象的key
             * 如果可以增加對象,直接遍歷category數組,增加一個content。但是現在需要從新賦值一個id,name,content
             */
            list.push({
                _id: category[i]._id,
                name: category[i].name,
                content: arr[i]
            });
        }
  • 第三種解決辦法
    lean屬性的作用:轉換mongoose查詢結果類型,從MongooseDocuments轉換爲JS Object,從而便於我們修改查詢結果。``
let category = await categoryModel.find().lean()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章