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
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?
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.