Django-haystack: `order_by` no funciona con` DecimalField`

Creado en 9 ago. 2011  ·  12Comentarios  ·  Fuente: django-haystack/django-haystack

Debido a que DecimalField se almacena como string cuando se indexa, no produce los resultados esperados cuando se usa order_by .

En lugar de ordenar por valor numérico, ordena los datos alfabéticamente.

Problema relacionado en el backend de Xapian aquí: https://github.com/notanumber/xapian-haystack/issues/84

needs review

Comentario más útil

Una solución para esto es almacenar el contenido de un campo decimal como un número entero. Por ejemplo, si tengo un modelo llamado MyModel con un campo decimal llamado precio, podría multiplicarlo por el número de lugares decimales y almacenarlo como un número entero.

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

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

Todos 12 comentarios

Quizás la mejor manera de abordar (rápidamente) esto sería actualizar la documentación DecimalField para indicar que order_by no es compatible.

A largo plazo, podría aparecer un mensaje de ADVERTENCIA en el registro de nivel cuando se intente la operación order_by en un DecimalField . Por motivos de rendimiento, la verificación del tipo de campo solo se puede realizar cuando el sitio está en modo DEBUG .

Una solución para esto es almacenar el contenido de un campo decimal como un número entero. Por ejemplo, si tengo un modelo llamado MyModel con un campo decimal llamado precio, podría multiplicarlo por el número de lugares decimales y almacenarlo como un número entero.

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

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

Esto parece funcionar para elasticsearch pero no para solr.

El error aparentemente también se aplica a Whoosh.

Las consultas de rango también fallan en elasticsearch.

+1

Me encontré con este mismo problema usando SolrBackend. Estamos ordenando por un campo que contiene un número entre 0.0 - 1.0 que representa un algoritmo de puntuación complejo. Al ordenar por cadena, eso significa que los elementos con una puntuación muy pequeña se ordenan por encima de aquellos con puntuaciones más altas, por ejemplo, 9e-08

En realidad, una solución obvia es usar un campo flotante en su lugar (realmente no importa para mis propósitos).

Esto es bastante malo. Si no se va a arreglar, pero simplemente se documenta como "order_by no funciona", entonces creo que deberíamos desaprobar el tipo de campo o tener una advertencia clara en la lista de tipos de campo, porque sería fácil de usar por error, y la reparación es lenta si tiene una base de datos grande.

tampoco funciona para elasticsearch

: +1:

@JoeJasinski muchas gracias, tu respuesta me ayudó

Una solución para esto es almacenar el contenido de un campo decimal como un número entero. Por ejemplo, si tengo un modelo llamado MyModel con un campo decimal llamado precio, podría multiplicarlo por el número de lugares decimales y almacenarlo como un número entero.

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

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

¿Y luego?
MyIndex.objects.all().order_by('prepare_price') ? ¿Derecha?

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

jpatel3 picture jpatel3  ·  4Comentarios

eromoe picture eromoe  ·  9Comentarios

matclayton picture matclayton  ·  7Comentarios

SteveByerly picture SteveByerly  ·  8Comentarios

ajwillo picture ajwillo  ·  3Comentarios