【问题标题】:How can I parse complex query operations using Sequelize.js?如何使用 Sequelize.js 解析复杂的查询操作?
【发布时间】:2020-10-02 02:15:28
【问题描述】:

我有一个Option 表,它有一个question_id 作为表Questions 的外键。 然后在Questions 表中,我有两个外键,即question_category_idsection_id。对于第一个选项部分,我可以应用 LEFT OUTER JOIN 查询,但我还需要获取 Question_CategorySection 表的值。 让我先弄清楚我希望我的输出是怎样的:

输出 JSON

"questions": [
  {
    "id": 9,
    "isActive": true,
    "question_text": "What is abc ?",
    "createdBy": "avis",
    "questionCategory": {
      "id": 1,
      "name": "aptitude"
    },
    "section": {
      "id": 1,
      "marks": 5
    },
    "options": [
      {
        "id": 1,
        "answer": true,
        "option_text": "A",
        "question_id": 9
      },
      {
        "id": 2,
        "answer": false,
        "option_text": "B",
        "question_id": 9
      }
    ]
  }
]

现在我正在指定我的数据库模型:

question_category.js

module.exports = (sequelize, Sequelize) => {
    const QuestionCategory = sequelize.define('question_category', {
        id:{ type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true }, 
        isActive: { type: Sequelize.BOOLEAN, allowNull: false },
        question_category_name: { type: Sequelize.STRING, allowNull: false },
        createdBy: { type: Sequelize.STRING, allowNull: false },
        createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
    }, { timestamps: false });

    return QuestionCategory;
};

section.js

module.exports = (sequelize, Sequelize) => {
    const Section = sequelize.define('section', {
        id: { type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true },
        isActive: { type: Sequelize.BOOLEAN, allowNull: false },
        marks_per_question: { type: Sequelize.INTEGER, allowNull: false },
        createdBy: { type: Sequelize.STRING, allowNull: false },
        createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
    }, { timestamps: false });

    return Section;
};

question.js

module.exports = (sequelize, Sequelize) => {
    const Questions = sequelize.define('questions', {
        id:{ type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true }, 
        isActive: { type: Sequelize.BOOLEAN, allowNull: false },
        question_text: { type: Sequelize.STRING, allowNull: false },
        createdBy: { type: Sequelize.STRING, allowNull: false },
        createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
    }, { timestamps: false });

    return Questions;
};

option.js

module.exports = (sequelize, Sequelize) => {
    const Options = sequelize.define('options', {
        id:{ type: Sequelize.BIGINT, autoIncrement: true, allowNull: false, primaryKey: true }, 
        answer: { type: Sequelize.BOOLEAN, allowNull: true },
        option_text: { type: Sequelize.STRING, allowNull: false },
        createdAt: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }
    }, { timestamps: false });

    return Options;
};

database.js 即用于导出模型的主 js 文件中,我已将模型关联如下:

const dbConfig = require('../config/db.config');
const Sequelize = require('sequelize');

const sequelize = new Sequelize(
    dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD,
    {
        host: dbConfig.HOST,
        port: dbConfig.PORT,
        dialect: 'mysql',
        operatorsAliases: 0
    }
);

sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
}).catch(err => {
    console.error('Unable to connect to the database:', err);
});

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

db.QuestionCategory = require('./question_model/question_category')(sequelize, Sequelize);
db.Section = require('./question_model/section')(sequelize, Sequelize);
db.Question = require('./question_model/question')(sequelize, Sequelize);
db.Option = require('./question_model/option')(sequelize, Sequelize);

// Relating Question Category with Questions
db.QuestionCategory.hasMany(db.Question, {
    foreignKey: 'question_category_id',
    sourceKey: 'id'
});
db.Question.belongsTo(db.QuestionCategory, {
    foreignKey: 'question_category_id',
    targetKey: 'id'
});

// Relating Sections with Questions
db.Section.hasMany(db.Question, {
    foreignKey: 'section_id',
    sourceKey: 'id'
});
db.Question.belongsTo(db.Section, {
    foreignKey: 'section_id',
    targetKey: 'id'
});

// Relating Questions with Options
db.Question.hasMany(db.Option, {
    foreignKey: 'question_id',
    sourceKey: 'id'
});
db.Option.belongsTo(db.Question, {
    foreignKey: 'question_id',
    targetKey: 'id'
});

这就是我的结构。 现在为了实现上述输出格式,我编写了以下逻辑,但它没有输出正确的 JSON:

const db = require('../models/database');
const errors = require('../config/errors').errors;

exports.viewQuestion = (req, res, next) => {
  try {
    db.Question.findAll({ 
      attributes: { exclude: ['createdAt','section_id','question_category_id'] },
      include: [{
        model: db.Option,
        attributes: { exclude: ['createdAt'] }
      }]
    }).then(data => {
        if(data.length == 0) {
          return res.status(200).send({
            status: 200,
            questions: 'No Data'
          });
        }
        db.QuestionCategory.findAll({
          attributes: { exclude: ['createdBy','createdAt','isActive'] },
          include: db.Question,
          attributes: { exclude: ['id','isActive','question_text','createdBy','createdAt','section_id'] }
        }).then(question_category => {
          Object.assign(data[0], { 'questionCategories': question_category });
          res.status(200).send({
            status: 200,
            questions: data
          });
        });
      }).catch(err => {
        return res.status(204).send(errors.MANDATORY_FIELDS);
      });
  } catch(err) {
    return res.status(204).send(errors.MANDATORY_FIELDS);
  }
};

我还没有为Section 部分编写逻辑,因为我正在逐步进行。通过编写此逻辑得到的输出是:

{
    "status": 200,
    "questions": [
        {
            "id": 9,
            "isActive": true,
            "question_text": "What is abc ?",
            "createdBy": "avis",
            "options": [
                {
                    "id": 1,
                    "answer": true,
                    "option_text": "A",
                    "question_id": 9
                },
                {
                    "id": 2,
                    "answer": false,
                    "option_text": "B",
                    "question_id": 9
                }
            ]
        }
    ]
}

questionCategories 没有反映在输出中。

请帮助我,因为我有更多这样的场景,我可以根据这个解决所有问题。

【问题讨论】:

    标签: javascript mysql node.js database sequelize.js


    【解决方案1】:

    如果您使用 Sequelize 通过模型从数据库中获取对象,那么您应该在添加一些属性之前将它们转换为普通对象。例如,如果你得到一个对象集合,你应该为每个对象调用get({ plain: true })

    const plainObj = data[0].get({ plain: true })
    Object.assign(plainObj, { 'questionCategories': question_category });
              res.status(200).send({
                status: 200,
                questions: plainObj
              });
    

    【讨论】:

    • 感谢您提供此信息。但是你能帮我怎样才能得到我想要的输出吗?我不认为我的逻辑会有所帮助,而且有点复杂
    • 为什么不在db.Question.findAllinclude 选项中添加QuestionCategory
    • 这行得通吗?我的意思是它会找到匹配的行吗??
    • 试试就知道了)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 2012-10-14
    • 1970-01-01
    • 2018-09-20
    相关资源
    最近更新 更多