我有一个表,它代表可以在前端重新排序的列表。我还有一个表,用于存储该列表中的项目。因此,订购信息与实际商品保持分开。当我重新排序列表时,说:
id item order
------------------
1 item-1 1
2 item-2 2
3 item-3 3
到
id item order
------------------
1 item-1 3
2 item-2 1
3 item-3 2
您可以看到订单列不再与id列对齐。为了确保一致的对象构建,我有一个泛型函数,该函数接受ID数组并在保存实际项目(而不是其顺序)的表上执行findAll()
查询。我遇到的问题是,当我要在同一数组中返回模型数组时,findAll()
查询似乎默认orderby
子句基于其传递的id将ID数组输入其中的顺序。
虽然我可以按ID的顺序执行findOne()
,但这似乎是一种低效的方法。
实际的功能是这样的:
async buildQuestion(question){
// check if question is array to allow for faster querying of multiple questions
if(Array.isArray(question)){
const ids = question.filter(item => item.id).map(item => item.id);
const questions = db.questions.findAll({
where: { id: ids },
include: [db.formats, db.categories, db.types, db.questionHints, db.questionVideos]
});
return questions.map(question => new Promise(resolve => _build(question).then(item => resolve(item))));
}else{
if (!question.id) throw new Error('question.id required at Builder.buildQuestion()');
question = await db.questions.findOne({
where: { id: question.id },
include: [db.formats, db.categories, db.types, db.questionHints, db.questionVideos]
});
return _build(question);
}
答案 0 :(得分:0)
AFAIK,用于订购SQL结果集的仅方式是使用order by
子句,因此您必须将当前订单添加到数据库表中才能实现目标。
如果这不可能,则可以编写js代码以将当前订单值添加到结果集中,然后进行排序。这可能比多个查询更有效,尤其是在结果集很大的情况下。
有些示例代码可以工作...虽然可能不是最干净的代码:)
let myOrder = [3, 1, 2];
User.findAll({
attributes: ['id', 'username',
[Sequelize.literal("0"), 'myOrder'] /* to hold desired order */
],
where : {id : myOrder}
})
.then(users => {
/* add desired sequence to result set */
for (let ord = 0; ord < myOrder.length; ord++) {
let usr = users.find(user => user.id == myOrder[ord]);
if (usr) {
usr.dataValues.myOrder = ord;
}
}
/* sort in desired order */
users.sort((a, b) => a.dataValues.myOrder - b.dataValues.myOrder);
res.send(users);
next();
});