Django Haystack对场的不同价值

时间:2013-11-17 18:49:46

标签: python django elasticsearch django-haystack searchqueryset

我正在使用Django Haystack + Elasticsearch + Django REST框架构建一个小型搜索引擎,我试图找出重现Django QuerySet的{​​{1}}方法的行为。

我的索引看起来像这样:

distinct

我希望能够做到以下几点:

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

然而,Haystack的sqs = SearchQuerySet().filter(content=my_search_query).distinct('item_id') 没有SearchQuerySet方法,所以我有点迷失。我试着面对该字段,然后使用返回的distinct列表查询Django,但这会失去Elasticsearch的性能,并且也无法使用Elasticsearch的排序功能。

有什么想法吗?

编辑:

示例数据:

示例数据:

item_id

正如您所看到的,同一个项目有多个VendorItem,但是在搜索时我只想为每个项目检索最多一个结果。因此,我需要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 ... ... 列是唯一/不同的。

我在item_id列上尝试过faceting,然后执行以下查询:

item_id

这里的主要问题是结果限制为100个项目,并且无法使用haystack进行排序。

1 个答案:

答案 0 :(得分:4)

我认为我能给你的最好建议是停止使用Haystack。

Haystack的默认后端(elasticsearch_backend.py)主要是用Solr编写的。我在haystack中发现了很多烦恼,但最大的烦恼是将所有查询打包成一个名为query_string的东西。使用查询字符串,他们可以使用lucene语法,但这也意味着丢失整个elasticsearch DSL。 lucene语法有一些优点,特别是如果这是你习惯的,但从弹性搜索的角度来看它是非常有限的。

此外,我认为您正在将RDBMS概念应用于搜索引擎。这并不是说你不应该得到你需要的结果,但方法通常是不同的。

如果不使用haystack,查询和检索此数据的方式可能会有所不同,因为haystack以更适合solr的方式创建索引而不是弹性搜索。

例如,在创建新索引时,haystack会为所有将在索引中的模型分配一个名为“modelresult”的“类型”。

所以,假设您有一些名为Items的实体和一些名为vendoritems的实体。

将它们放在同一个索引中,但将vendoritems作为一种供应商项目和具有项目类型的项目可能是合适的。

查询时,您将根据其余端点进行查询,例如localhost:9200/index/type (query)。 haystack实现的方式是通过django内容类型模块。因此,有一个名为“django_ct”的字段,当您只查找唯一的项目时,haystack查询并附加到您可能进行的任何查询。

为了说明上述内容:

此端点搜索所有索引

`localhost:9200/`

此端点搜索索引中的所有类型:

`localhost:9200/yourindex/`

此端点搜索索引中的类型:

`localhost:9200/yourindex/yourtype/`

并且此端点在索引中搜索两种指定类型:

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

回到haystack,您可以通过在查询中添加django_ct来获得唯一值,但可能不是您想要的。

你真正想做的是一个方面,可能你想使用术语方面。这可能是大海捞针中的一个问题,因为它A.)分析所有文本和B.)将store = True应用于所有字段(真的不是你想在elasticsearch中做的事情,而是你经常想要在solr中做的事情)。

您可以在elasticsearch(http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html#_ordering

中订购构面结果

我并不是说这是对干草堆的大满贯。我认为它在概念上做了很多事情。如果您只需索引单个模型(比如说博客)并让它快速返回结果,那就特别好了。

那就是说,我强烈建议使用elasticutils。 haystack中的一些概念是相似的,但它使用搜索dsl而不是query_string(但如果你愿意,你仍然可以使用query_string)。

请注意,我不认为你可以默认使用elasticutils来命令facet,但是你可以传递一个你想要的方面的python字典facet_raw方法(我不认为你可以在干草堆里做。)

您的最后一个选择是创建自己的haystack后端,继承现有的后端,只需在.facet()方法中添加一些功能,以允许按照上述dsl进行排序。