如何以数组的原始顺序返回sequelize findAll(array)?

时间:2019-12-04 01:25:42

标签: node.js sequelize.js

我有一个表,它代表可以在前端重新排序的列表。我还有一个表,用于存储该列表中的项目。因此,订购信息与实际商品保持分开。当我重新排序列表时,说:

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

1 个答案:

答案 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();
});
相关问题