2017-02-09 123 views
0

我目前暴力破解這個,但我相信有一個使用Sequelize,有問題的代碼更好的解決方案(使用的是Postgres):從Sequelize選擇隨機記錄的findAll

... 
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做到這一點,理想情況下不使用原始查詢?

謝謝

回答

3
Encounter.findOne({ order: 'random()' }).then((encounter) => { 
    // single random encounter 
}); 

random()應在PostgreSQL的情況下使用,在MySQL的情況下,你可能會使用rand()。你沒有指定你使用的數據庫。

編輯

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

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

如果將操作拆分爲兩個步驟會怎樣?

  1. 計數的行數在表中Encounter.count({ where: ... })
  2. 取該數量可以計算遭遇值。然後,如果你使用整數主鍵,你可以做一個Encounter.findById(encounterId)

即使這樣服用會更加高效的網絡,如果記錄在你的數據庫的數量變大。

0

這個代碼是作爲與MySQL和[email protected]爲那些需要測試的例子

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

     limit: 1, 

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