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] }); }