我正在使用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进行排序。
答案 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进行排序。