Django-haystack: `order_by` funktioniert nicht mit `DecimalField`

Erstellt am 9. Aug. 2011  ·  12Kommentare  ·  Quelle: django-haystack/django-haystack

Da DecimalField beim Indizieren als string gespeichert wird, liefert es nicht die erwarteten Ergebnisse, wenn order_by .

Anstatt nach numerischen Werten zu sortieren, werden die Daten stattdessen alphabetisch sortiert.

Verwandtes Problem im Xapian-Backend hier: https://github.com/notanumber/xapian-haystack/issues/84

needs review

Hilfreichster Kommentar

Eine Problemumgehung hierfür besteht darin, den Inhalt eines Dezimalfelds als Ganzzahl zu speichern. Wenn ich beispielsweise ein Modell namens MyModel mit einem Dezimalfeld namens price habe, könnte ich es mit der Anzahl der Dezimalstellen multiplizieren und als Ganzzahl speichern.

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

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

Alle 12 Kommentare

Der vielleicht beste Weg, dies (schnell) zu beheben, besteht darin, die Dokumentation zu DecimalField zu aktualisieren, um darauf hinzuweisen, dass order_by nicht unterstützt wird.

Längerfristig könnte eine Warnung im Level-Log ausgegeben werden, wenn die order_by Operation auf einem DecimalField versucht wird. Aus Leistungsgründen konnte die Überprüfung des Feldtyps nur durchgeführt werden, wenn sich die Site im DEBUG Modus befindet.

Eine Problemumgehung hierfür besteht darin, den Inhalt eines Dezimalfelds als Ganzzahl zu speichern. Wenn ich beispielsweise ein Modell namens MyModel mit einem Dezimalfeld namens price habe, könnte ich es mit der Anzahl der Dezimalstellen multiplizieren und als Ganzzahl speichern.

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

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

Dies scheint für Elasticsearch zu funktionieren, aber nicht für solr.

Der Fehler gilt offenbar auch für Whoosh.

Bereichsabfragen schlagen auch bei Elasticsearch fehl.

+1

Ich habe das gleiche Problem mit dem SolrBackend getroffen. Wir sortieren nach einem Feld, das eine Zahl zwischen 0,0 - 1,0 enthält, die einen komplexen Bewertungsalgorithmus darstellt. Bei der Sortierung nach String bedeutet dies, dass Elemente mit einer sehr kleinen Punktzahl über denen mit einer größeren Punktzahl sortiert werden, z. B. 9e-08

Ziemlich offensichtlich ist es, stattdessen ein Float-Feld zu verwenden (ist für meine Zwecke nicht wirklich wichtig).

Das ist ziemlich schlecht. Wenn es nicht behoben wird, sondern nur als "order_by funktioniert nicht" dokumentiert wird, sollten wir den Feldtyp meiner Meinung nach verwerfen oder eine klare Warnung in der Liste der Feldtypen haben, da es einfach wäre, ihn zu verwenden Fehler und langsam zu reparieren, wenn Sie eine große Datenbank haben.

funktioniert auch nicht für Elasticsearch

:+1:

@JoeJasinski vielen Dank, deine Antwort hat mir geholfen

Eine Problemumgehung hierfür besteht darin, den Inhalt eines Dezimalfelds als Ganzzahl zu speichern. Wenn ich beispielsweise ein Modell namens MyModel mit einem Dezimalfeld namens price habe, könnte ich es mit der Anzahl der Dezimalstellen multiplizieren und als Ganzzahl speichern.

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

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

Und dann?
MyIndex.objects.all().order_by('prepare_price') ? Rechts?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen