Javascript 如何使用Sequelize.js解析复杂的查询操作?
我有一个Javascript 如何使用Sequelize.js解析复杂的查询操作?,javascript,mysql,node.js,database,sequelize.js,Javascript,Mysql,Node.js,Database,Sequelize.js,我有一个选项表,它有一个问题id作为表问题的外键。 然后在Questions表中,我有两个外键,即question\u category\u id和section\u id。对于第一个选项部分,我可以应用左外部联接查询,但我还需要获取问题(u)类别和部分表的值。 首先让我澄清一下我希望我的输出是什么: 输出JSON "questions": [ { "id": 9, "isActive": true, &qu
选项
表,它有一个问题id
作为表问题
的外键。
然后在Questions
表中,我有两个外键,即question\u category\u id
和section\u id
。对于第一个选项部分,我可以应用左外部联接
查询,但我还需要获取问题(u)类别
和部分
表的值。
首先让我澄清一下我希望我的输出是什么:
输出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
}
]
}
]
现在我指定我的数据库模型:
问题_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;
};
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;
};
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;
};
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;
};
section.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;
};
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;
};
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;
};
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;
};
question.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;
};
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;
};
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;
};
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;
};
option.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;
};
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;
};
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;
};
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);
}
};
我还没有为部分编写逻辑,因为我正在一步一步地进行。通过编写此逻辑,我得到的输出是:
{
"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
没有反映在输出中
请帮助我,因为我有更多这样的场景,我可以根据这些场景解决所有问题。如果您使用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.findAll的include
选项中添加QuestionCategory
?这样行吗?我的意思是,它会找到匹配的行吗?只要尝试一下,你就会发现)