从Sequelize findAll中选择一个随机记录

sme*_*dev 6 javascript node.js sequelize.js

我目前正在蛮力这个,但我相信有一个更好的解决方案,使用Sequelize,有问题的代码(使用postgres):

...
then((tile_data) => {
  return Encounter.findAll({
    where: {
      level: tile_data.dataValues.level
    },
    transaction: transaction_data
  }).then((encounter_data) => {
    let encounter = encounter_data[Math.floor((Math.random() * encounter_data.length))].dataValues
    return Battle.create({
      character_id: character_data.dataValues.id,
      encounter_id: encounter.id,
      encounter_hp: encounter.max_hp,
      encounter_mana: encounter.max_mana
    }, {
      transaction: transaction_data
    })
...
Run Code Online (Sandbox Code Playgroud)

除了看似'丑陋',使用这段代码我将所有ENCOUNTERS加载到内存中只是为了从阵列中提取一个元素.

有没有人知道如何通过Sequelize这样做,理想情况下不使用原始查询?

谢谢

l2y*_*sho 14

我认为这个解决方案是最清楚的。您应该使用 sequelize 实例中的随机函数

const sequelize = new Sequelize(url, opts);
Run Code Online (Sandbox Code Playgroud)

推荐使用 sequelize-cli 生成初始模式,它会自动导出 sequelize 变量。

Encounter.findOne({ 
  order: sequelize.random() 
});
Run Code Online (Sandbox Code Playgroud)

同样使用这种方法,如果您将 db 方言从 postgres 更改为 MySQL 或返回,则无需解决RAND()vsRANDOM()问题。


And*_*ono 9

你可以试试这个:

Encounter.findAll({ order: Sequelize.literal('rand()'), limit: 5 }).then((encounters) => {
        // single random encounter
    }); 
Run Code Online (Sandbox Code Playgroud)

别忘了要求Sequelize

  • 请注意,对于 postgres,函数名称文字将是“random()”。 (7认同)

pio*_*ias 7

Encounter.findOne({ order: 'random()' }).then((encounter) => {
    // single random encounter
});
Run Code Online (Sandbox Code Playgroud)

random()在PostgreSQL的情况下应该使用,如果是MySQL你可能会使用rand().您没有指定使用的数据库.

编辑

或者如果你真的想使用.findAll():

Encounter.findAll({ order: 'random()', limit: 1 }).then((encounter) => {
    // single random encounter
}); 
Run Code Online (Sandbox Code Playgroud)


dec*_*283 5

推荐方式,适用于所有数据库方言,截至今天,2019 年 5 月 2 日

order: sequelize.random()
Run Code Online (Sandbox Code Playgroud)

  • 应该在sequelize实例中提及它,而不是在sequelize模块中 (3认同)