Django-haystack: `order_by` ne fonctionne pas avec `DecimalField`

Créé le 9 août 2011  ·  12Commentaires  ·  Source: django-haystack/django-haystack

É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

needs review

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.

class MyIndex(SearchIndex):
    ...
    price = IntegerField(model_attr='price')

    def prepare_price(self, obj):
        return int(obj.price * Decimal('100'))

Tous les 12 commentaires

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?

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

mdf-github picture mdf-github  ·  8Commentaires

ryanmrubin picture ryanmrubin  ·  6Commentaires

ajwillo picture ajwillo  ·  3Commentaires

bforchhammer picture bforchhammer  ·  8Commentaires

BouchaaraAdil picture BouchaaraAdil  ·  5Commentaires