Étant donné que DecimalField
est stocké sous forme de string
lors de l'indexation, il ne produit pas les résultats attendus lors de l'utilisation de order_by
.
Au lieu de trier par valeur numérique, il trie les données par ordre alphabétique.
Problème connexe sur le backend Xapian ici : https://github.com/notanumber/xapian-haystack/issues/84
Le meilleur moyen de résoudre ce problème (rapidement) serait peut-être de mettre à jour la documentation de DecimalField
pour indiquer que order_by
n'est pas pris en charge.
À plus long terme, un message de journal de niveau d'AVERTISSEMENT pourrait être généré lorsque l'opération order_by
est tentée sur un DecimalField
. Pour des raisons de performances, la vérification du type de champ ne pourra se faire que lorsque le site est en mode DEBUG
.
Une solution de contournement consiste à stocker le contenu d'un champ décimal sous forme d'entier. Par exemple, si j'ai un modèle appelé MyModel avec un champ décimal appelé prix, je pourrais le multiplier par le nombre de décimales et le stocker sous forme d'entier.
class MyIndex(SearchIndex):
...
price = IntegerField(model_attr='price')
def prepare_price(self, obj):
return int(obj.price * Decimal('100'))
Cela semble fonctionner pour Elasticsearch mais pas pour Solr.
Le bogue s'applique apparemment aussi à Whoosh.
Les requêtes de plage échouent également sur Elasticsearch.
+1
J'ai rencontré ce même problème en utilisant SolrBackend. Nous trions par un champ qui contient un nombre compris entre 0,0 et 1,0 représentant un algorithme de notation complexe. Lors du tri par chaîne, cela signifie que les éléments avec un très petit score sont triés au-dessus de ceux avec des scores plus élevés, par exemple 9e-08
Assez, un contournement évident consiste à utiliser un champ flottant à la place (cela n'a pas vraiment d'importance pour mes besoins).
C'est assez mauvais. Si cela ne va pas être corrigé, mais simplement documenté comme "order_by ne fonctionne pas", alors je pense que nous devrions déprécier le type de champ ou avoir un avertissement clair dans la liste des types de champs, car il serait facile de l'utiliser par erreur et lente à réparer si vous avez une grande base de données.
ne fonctionne pas non plus pour elasticsearch
:+1:
@JoeJasinski merci beaucoup, votre réponse m'a aidé
Une solution de contournement consiste à stocker le contenu d'un champ décimal sous forme d'entier. Par exemple, si j'ai un modèle appelé MyModel avec un champ décimal appelé prix, je pourrais le multiplier par le nombre de décimales et le stocker sous forme d'entier.
class MyIndex(SearchIndex): ... price = IntegerField(model_attr='price') def prepare_price(self, obj): return int(obj.price * Decimal('100'))
Puis?
MyIndex.objects.all().order_by('prepare_price')
? Droit?
Commentaire le plus utile
Une solution de contournement consiste à stocker le contenu d'un champ décimal sous forme d'entier. Par exemple, si j'ai un modèle appelé MyModel avec un champ décimal appelé prix, je pourrais le multiplier par le nombre de décimales et le stocker sous forme d'entier.