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]
});
}
複製程式碼