• 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()
    
  • 相关阅读:
    qemu-kvm 基础
    QEMU、KVM、libvirt三者间的关系
    QEMU和KVM的关系
    生死乃世间常事,若真爱,请许我出家
    净土大经科注(第四回)第28集文字稿
    净土大经科注 第18集(部分,文字不全)
    二零一四净土大经科注  (第十二集文字稿)
    净土大经科注(第四回)第14集文字稿
    陈静瑜老师系列讲座汇编
    陈静瑜老师:人这个烦恼习气真的是很难改,如果没有坚定的决心,像《了凡四训》上说的那种勇猛心,那种畏惧心、羞耻心,很难回头改过。
  • 原文地址:https://www.cnblogs.com/luxiaoyao/p/10552905.html
Copyright © 2020-2023  润新知