Django-haystack: `order_by` não funciona com` DecimalField`

Criado em 9 ago. 2011  ·  12Comentários  ·  Fonte: django-haystack/django-haystack

Como DecimalField é armazenado como string durante a indexação, ele não produz os resultados esperados ao usar order_by .

Em vez de ordenar por valor numérico, ele classifica os dados em ordem alfabética.

Problema relacionado no back-end Xapian aqui: https://github.com/notanumber/xapian-haystack/issues/84

needs review

Comentários muito úteis

Uma solução alternativa para isso é armazenar o conteúdo de um campo decimal como um número inteiro. Por exemplo, se eu tiver um modelo denominado MeuModelo com um campo Decimal denominado preço, poderia multiplicá-lo pelo número de casas decimais e armazenar como um inteiro.

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

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

Todos 12 comentários

Talvez a melhor maneira de resolver isso (rapidamente) seja atualizar a documentação DecimalField para indicar que order_by não é suportado.

A longo prazo, uma mensagem de nível de AVISO poderia ser gerada quando a operação order_by fosse tentada em um DecimalField . Por motivos de desempenho, a verificação do tipo de campo só pode ser feita quando o site está no modo DEBUG .

Uma solução alternativa para isso é armazenar o conteúdo de um campo decimal como um número inteiro. Por exemplo, se eu tiver um modelo denominado MeuModelo com um campo Decimal denominado preço, poderia multiplicá-lo pelo número de casas decimais e armazenar como um inteiro.

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

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

Isso parece funcionar para elasticsearch, mas não para solr.

O bug aparentemente se aplica ao Whoosh também.

Consultas de intervalo também falham em elasticsearch.

+1

Eu encontrei esse mesmo problema usando o SolrBackend. Estamos classificando por um campo que contém um número entre 0,0 - 1,0, representando um algoritmo de pontuação complexo. Ao classificar por string, isso significa que os elementos com uma pontuação muito pequena são classificados acima daqueles com pontuações maiores, por exemplo, 9e-08

Justamente, uma solução alternativa óbvia é usar um campo flutuante em vez disso (realmente não importa para meus propósitos).

Isso é muito ruim. Se não vai ser corrigido, mas apenas documentado como "order_by não funciona", então acho que devemos descontinuar o tipo de campo ou ter um aviso claro na lista de tipos de campo, porque seria fácil de usar por erro e lento para reparar se você tiver um grande banco de dados.

também não funciona para elasticsearch

: +1:

@JoeJasinski muito obrigado, sua resposta me ajudou

Uma solução alternativa para isso é armazenar o conteúdo de um campo decimal como um número inteiro. Por exemplo, se eu tiver um modelo denominado MeuModelo com um campo Decimal denominado preço, poderia multiplicá-lo pelo número de casas decimais e armazenar como um inteiro.

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

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

E então?
MyIndex.objects.all().order_by('prepare_price') ? Direito?

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

pascallando picture pascallando  ·  4Comentários

ryanmrubin picture ryanmrubin  ·  6Comentários

SacNaturalFoods picture SacNaturalFoods  ·  5Comentários

SteveByerly picture SteveByerly  ·  8Comentários

BouchaaraAdil picture BouchaaraAdil  ·  5Comentários