django haystack backed by elasticsearch seems to order Decimal as string

445 views Asked by At

I have this model (a django-oscar Product):

class Product(AbstractProduct):
    # ...
    price_display = models.DecimalField(decimal_places=2, max_digits=12, blank=True, null=True)
    # ...

Indexed by haystack:

class ProductIndex(indexes.SearchIndex, indexes.Indexable):
    # ...
    price = indexes.DecimalField(null=True)
    # ...
    def prepare_price(self, obj):
        return obj.price_display or Decimal('0.0')

Haystack is backed by elasticsearch

pip freeze | grep elastic
elasticsearch==1.6.0
pyelasticsearch==1.4
pip freeze | grep hays
django-haystack==2.1.0

now this queryset :

# ...
qs = qs.filter(text__contains=q)
qs = qs.order_by('price')

returns the (correctly found) objects with prices ordered in this way:

120  130  24  300 ... 9

Cant figure what is wrong...

1

There are 1 answers

0
simone cittadini On

Haystack (at least with the versions I'm using) sends a Decimal field to elastic as a: "price":{"type":"string","store":true,"term_vector":"with_positions_offsets","analyzer":"snowball"},

so it doesnt "seem" to order like a string, it's ordering a string ...

I've changed my code to use float, not such a problem, we are not talking money anymore at this point.

price = indexes.FloatField(null=True)

def prepare_price(self, obj):
    if obj.price_display:
        return float(str(obj.price_display))
    return float('0.0')

Now it sends the field as: "price":{"type":"float","index":"analyzed","store":true},

and ordering works, yay