Pergunta

Eu estou construindo um pequeno motor de pesquisa utilizando o Django Palheiro + Elasticsearch + Django RESTO do Quadro, e eu estou tentando descobrir reproduzir o comportamento de uma Django QuerySet's distinct o método.

O meu índice é algo como isto:

class ItemIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    item_id = indexes.IntegerField(faceted=True)

    def prepare_item_id(self, obj):
        return obj.item_id

O que eu gostaria de ser capaz de fazer é o seguinte:

sqs = SearchQuerySet().filter(content=my_search_query).distinct('item_id')

No entanto, Palheiro do SearchQuerySet não tem um distinct o método, então, eu estou meio perdido.Eu tentei de facetamento o campo e, em seguida, consultar Django usando a lista devolvida de item_id's, mas este perde o desempenho do Elasticsearch, e também torna impossível a utilização do Elasticsearch recursos de classificação.

Quaisquer pensamentos?

EDITAR:

Os dados de exemplo:

Os dados de exemplo:

Item Model
==========

id  title
1   'Item 1'
2   'Item 2'
3   'Item 3'


VendorItem Model << the table in question
================

id  item_id  vendor_id  lat   lon
1   1        1          38    -122
2   2        1          38.2  -121.8
3   3        2          37.9  -121.9
4   1        2          ...   ...
5   2        2          ...   ...
6   2        3          ...   ...

Como você pode ver, existem vários VendorItem para o mesmo Item, no entanto, quando a pesquisa eu só quero recuperar mais de um resultado para cada item.Portanto, eu preciso que o item_id coluna única/distintas.

Eu tentei de facetamento no item_id coluna e, em seguida, executar a consulta seguinte:

facets = SearchQuerySet().filter(content=query).facet('item_id')
counts = sqs.facet_counts()

# ids will look like: [345, 892, 123, 34,...]
ids = [i[0] for i in counts['fields']['item_id']]

items = VendorItem.objects.filter(vendor__lat__gte=latMin,
    vendor__lon__gte=lonMin, vendor__lat__lte=latMax,
    vendor__lon__lte=lonMax, item_id__in=ids).distinct(
        'item').select_related('vendor', 'item')

O principal problema aqui é que os resultados são limitados a 100 itens, e eles não podem ser classificados de acordo com palheiro.

Foi útil?

Solução

Eu acho que o melhor conselho que posso dar é para parar de usar Palheiro.

Palheiro do padrão de back-end (o elasticsearch_backend.py) é, principalmente, escrito com o Solr em mente.Há um monte de aborrecimentos que eu encontrar no palheiro, mas o maior tem que ser que embala todas as consultas em algo chamado query_string.Usando a seqüência de caracteres de consulta, eles podem usar o lucene sintaxe, mas também significa perder todo o elasticsearch DSL.O lucene sintaxe tem algumas vantagens, especialmente se é isso que você está acostumado, mas é muito limitante de uma elasticsearch ponto de vista.

Além disso, eu acho que você está aplicando um RDBMS conceito para um motor de busca.O que não quer dizer que você não deve obter os resultados que você precisa, mas a abordagem é muitas vezes diferente.

A maneira que você pode consultar e recuperar esses dados podem ser diferentes se você não usar o palheiro porque palheiro cria índices de uma forma mais adequada para o solr do que para o elasticsearch.

Por exemplo, na criação de um novo índice, o palheiro para atribuir um tipo de" chamado "modelresult" para todos os modelos que vão em um índice.

Então, vamos dizer que você tenha algumas entidades chamado de Itens e algumas outras entidades chamado vendoritems.

Ele pode ser adequado para ter os dois no mesmo índice, mas com vendoritems como um tipo de vendoritems e itens de ter um tipo de itens.

Ao consultar, em seguida, consulta com base no resto ponto final, então, algo como localhost:9200/index/type (query).A forma palheiro alcança é isso é através de django tipos de conteúdo do módulo.Assim, há um campo chamado "django_ct" que palheiro consultas e anexa para qualquer consulta que você pode fazer quando você está olhando apenas para itens exclusivos.

Para ilustrar o acima:

Este ponto de extremidade de pesquisas através de todos os índices

`localhost:9200/`

Este ponto de extremidade de pesquisas em todos os tipos de índice:

`localhost:9200/yourindex/`

Este ponto de extremidade de pesquisas em um tipo dentro de um índice:

`localhost:9200/yourindex/yourtype/`

e este ponto de extremidade de pesquisas em dois tipos especificados dentro de um índice:

`localhost:9200/yourindex/yourtype,yourothertype/`

De volta ao palheiro, porém, você pode, possivelmente, obter valores exclusivos adicionando um django_ct para sua consulta, mas provavelmente não é isso que você quer.

O que você realmente quer fazer é uma faceta, e provavelmente você quiser usar o termo facetas.Isso poderia ser um problema no palheiro, porque A.) analisa todo o texto e b) aplica-se loja=True para todos os campos (realmente não é algo que você quer fazer em elasticsearch, mas algo que muitas vezes você quer fazer no solr).

Você pode encomendar faceta resultados em elasticsearch (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html#_ordering)

Não quero dizer, para que este seja um slam no palheiro.Eu acho que ele faz um monte de coisas direito conceitualmente.É especialmente bom se tudo o que você precisa fazer é índice de um único modelo (como dizem de um blog e só tenho que retornar rapidamente os resultados.

O que disse, eu recomendo usar elasticutils.Alguns dos conceitos do palheiro são semelhantes, mas usa a busca dsl, ao invés de incluir query_string (mas você ainda pode usar query_string se você queria).

Esteja avisado, porém, eu não acho que você pode encomendar facetas usando elasticutils por padrão, mas você pode apenas passar em python o dicionário das facetas que você deseja facet_raw método (algo que eu não acho que você pode fazer em palheiro).

A sua última opção é criar seu próprio palheiro back-end, herdar da existente back-end e apenas adicionar alguma funcionalidade ao .faceta() método para permitir para o pedido de acordo com o acima dsl.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top