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

时间:2017-02-09 20:25:50

标签: 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
    })
...

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

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

谢谢

9 个答案:

答案 0 :(得分:8)

random()
对于PostgreSQL,应该使用

rand(),对于MySQL,你可能会使用.findAll()。您没有指定使用的数据库。

修改

或者如果你真的想使用Encounter.findAll({ order: 'random()', limit: 1 }).then((encounter) => { // single random encounter });

type ScapholdSchema {
  id: ID!
  name: String!
  description: String
  types: [ScapholdType]
}

答案 1 :(得分:5)

你可以试试这个:

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

别忘了要求Sequelize

答案 2 :(得分:1)

如果将操作分为两个步骤怎么办?

  1. 计算表Encounter.count({ where: ... })
  2. 中的行数
  3. 取该数字可以计算遇到的值。然后,如果您对主键使用整数,则可以执行Encounter.findById(encounterId)
  4. 如果数据库中的记录数量变大,即使采用这种方法也会提高网络效率。

答案 3 :(得分:1)

此代码作为使用mysql和sequelize@4.22.5测试的示例提供给有需要的人

   Encounter.findAll({
      order: [
        [Sequelize.literal('RAND()')]
      ],

      limit: 1,

    }).then((resp) => {
      callback(null, resp)
    })

答案 4 :(得分:1)

我们可以轻松地使用findOne +订单rand:

...
import Sequelize from 'sequelize';
...

MyModel.findOne({
  order: [
    Sequelize.fn( 'RAND' ),
  ]
});

答案 5 :(得分:0)

对于所有数据库方言,推荐的方式是: 19年5月2日

order: sequelize.random()

答案 6 :(得分:0)

我认为这种解决方案是最清晰的。您应该使用续集实例中的随机函数

const sequelize = new Sequelize(url, opts);

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

Encounter.findOne({ 
  order: sequelize.random() 
});

使用这种方法,如果您将db方言从Postgres更改为MySQL或重新更改为MySQL,则无需解决RAND()RANDOM()问题。

答案 7 :(得分:0)

这适用于Postgres findAll和findAndCountAll。

order: Sequelize.literal('random()')

答案 8 :(得分:0)

截至2020年10月的今天。

在Sequelize mysql中,以下代码有效:

exports.uniqueRegistercodes = async (req) => {
    // console.log("code");
    const code = await registercodesModal.findAll({ order: db.sequelize.random(), limit: 1 });
    console.log("DATA CODE...");
    return code;
}