Il problema con select que from Question que order by RAND()
è che il DB ordinerà tutti i record prima di restituire un articolo. Quindi è costoso in grandi serie di dati.
Un modo più economico per raggiungere questo obiettivo consiste in due fasi:
- Find totale di record da dove si selezionarne uno.
- Ottieni un oggetto a caso in questo set.
di farlo in MySql, per esempio, si può fare:
select count(*) from question;
// using any programming language, choose a random number between 0 and count-1 (let's save this number in rdn), and finally
select * from question LIMIT $rdn, 1;
Ok, ma per fare questo nei dati primavera è necessario creare alcune query native ...
Fortunatamente, possiamo usare l'impaginazione per risolverlo. Nell'interfaccia Repository, creare i metodi (alcuni repository ha questo senza bisogno di definirla):
Long count();
Page<Question> findAll(Pageable pageable);
E nel vostro servizio che potete utente repository nel seguente modo:
public Question randomQuestion() {
Long qty = questionRepository.countAll();
int idx = (int)(Math.random() * qty);
Page<Question> questionPage = questionRepository.findAll(new PageRequest(idx, 1));
Question q = null;
if (questionPage.hasContent()) {
q = questionPage.getContent().get(0);
}
return q;
}
fonte
2017-03-27 18:45:54
Questo è uno di quelle risposte perfette in cui (a) è * esattamente * ciò di cui avevo bisogno e (b) Google e io non siamo riusciti a trovare qualcos'altro da vicino. Ma penso che tu abbia un refuso: non dovrebbe "countAll()" essere "count()"? – fivedogit