Karena DecimalField
disimpan sebagai string
saat pengindeksan, itu tidak menghasilkan hasil yang diharapkan saat menggunakan order_by
.
Alih-alih mengurutkan berdasarkan nilai numerik, itu malah mengurutkan data menurut abjad.
Masalah terkait pada backend Xapian di sini: https://github.com/notanumber/xapian-haystack/issues/84
Mungkin cara terbaik untuk (dengan cepat) mengatasi hal ini adalah dengan memperbarui dokumentasi DecimalField
untuk menunjukkan bahwa order_by
tidak didukung.
Dalam jangka panjang, pesan log level PERINGATAN dapat dikeluarkan ketika operasi order_by
dicoba pada DecimalField
. Untuk alasan kinerja, verifikasi jenis bidang hanya dapat dilakukan ketika situs dalam mode DEBUG
.
Salah satu solusi untuk ini adalah menyimpan konten bidang desimal sebagai bilangan bulat. Misalnya, jika saya memiliki model bernama MyModel dengan bidang Desimal yang disebut harga, saya dapat mengalikannya dengan jumlah tempat desimal dan menyimpannya sebagai bilangan bulat.
class MyIndex(SearchIndex):
...
price = IntegerField(model_attr='price')
def prepare_price(self, obj):
return int(obj.price * Decimal('100'))
Ini tampaknya berfungsi untuk elasticsearch tetapi tidak untuk solr.
Bug tampaknya berlaku untuk Whoosh juga.
Kueri rentang juga gagal di elasticsearch.
+1
Saya mengalami masalah yang sama menggunakan SolrBackend. Kami mengurutkan berdasarkan bidang yang berisi angka antara 0,0 - 1,0 yang mewakili algoritma penilaian yang kompleks. Saat mengurutkan berdasarkan string, artinya elemen dengan skor yang sangat kecil diurutkan di atas elemen dengan skor lebih besar, misalnya 9e-08
Cukup, solusi yang jelas adalah menggunakan bidang float sebagai gantinya (tidak terlalu penting untuk tujuan saya).
Ini sangat buruk. Jika itu tidak akan diperbaiki, tetapi hanya didokumentasikan sebagai "order_by tidak berfungsi", maka saya pikir kita harus menghentikan jenis bidang atau memiliki peringatan yang jelas dalam daftar jenis bidang, karena akan mudah digunakan oleh kesalahan, dan lambat untuk diperbaiki jika Anda memiliki database yang besar.
juga tidak berfungsi untuk elasticsearch
:+1:
@JoeJasinski terima kasih banyak, jawaban Anda membantu saya
Salah satu solusi untuk ini adalah menyimpan konten bidang desimal sebagai bilangan bulat. Misalnya, jika saya memiliki model bernama MyModel dengan bidang Desimal yang disebut harga, saya dapat mengalikannya dengan jumlah tempat desimal dan menyimpannya sebagai bilangan bulat.
class MyIndex(SearchIndex): ... price = IntegerField(model_attr='price') def prepare_price(self, obj): return int(obj.price * Decimal('100'))
Lalu?
MyIndex.objects.all().order_by('prepare_price')
? Benar?
Komentar yang paling membantu
Salah satu solusi untuk ini adalah menyimpan konten bidang desimal sebagai bilangan bulat. Misalnya, jika saya memiliki model bernama MyModel dengan bidang Desimal yang disebut harga, saya dapat mengalikannya dengan jumlah tempat desimal dan menyimpannya sebagai bilangan bulat.