分面搜索
该库提供了一个简单的抽象,旨在帮助您为数据开发分面导航。
注意
此 API 处于实验阶段,可能会发生变化。欢迎任何反馈。
配置
在声明 FacetedSearch
子类时,您可以提供多个配置选项(作为类属性)。
index
要搜索的索引名称(作为字符串),默认为
'_all'
。doc_types
要使用的
Document
子类或字符串列表,默认为['_all']
。fields
要搜索的文档类型上的字段列表。该列表将传递给
MultiMatch
查询,因此可以包含提升值 ('title^5'
),默认为['*']
。facets
要显示/过滤的分面字典。键是显示的名称,值应该是任何
Facet
子类的实例,例如:{'tags': TermsFacet(field='tags')}
分面
有几种不同的分面可用。
TermsFacet
提供根据字段的值将文档分成组的选项,例如
TermsFacet(field='category')
DateHistogramFacet
将文档分成时间间隔,例如:
DateHistogramFacet(field="published_date", calendar_interval="day")
HistogramFacet
类似于
DateHistogramFacet
,但用于数值:HistogramFacet(field="rating", interval=2)
RangeFacet
允许您为数值字段定义自己的范围:
RangeFacet(field="comment_count", ranges=[("few", (None, 2)), ("lots", (2, None))])
NestedFacet
只是一个简单的分面,它包装另一个分面以提供对嵌套文档的访问:
NestedFacet('variants', TermsFacet(field='variants.color'))
默认情况下,分面结果将只计算文档计数,如果您希望使用不同的指标,可以将任何单值指标聚合作为 metric
关键字参数传递 (TermsFacet(field='tags', metric=A('max', field=timestamp))
)。在指定 metric
时,结果将默认按该指标降序排序。要将其更改为升序,请指定 metric_sort="asc"
,要仅按文档计数排序,请使用 metric_sort=False
。
高级
如果您需要任何自定义行为或修改,只需覆盖一个或多个负责类功能的方法。
search(self)
负责构建
Search
对象。如果您想自定义搜索对象(例如,通过添加仅针对已发布文章的全局过滤器),请覆盖此方法。query(self, search)
添加搜索的查询位置(如果指定了搜索输入),默认情况下使用
MultiField
查询。如果您想修改使用的查询类型,请覆盖此方法。highlight(self, search)
定义
Search
对象上的突出显示,并返回一个新的对象。默认行为是在为搜索指定的所有字段上突出显示。
用法
自定义子类可以为空实例化以提供空搜索(匹配所有内容),或者使用 query
、filters
和 sort
实例化。
query
用于传入要执行的查询文本。如果传入
None
(默认),将使用MatchAll
查询。例如'python web'
filters
是一个字典,包含您希望应用的所有分面过滤器。使用分面的名称(来自
.facets
属性)作为键,以及一个可能的值作为值。例如{'tags': 'python'}
。sort
是结果应按其排序的字段元组或列表。各个字段的格式应与传递给
sort()
的格式相同。
响应
从 FacetedSearch
对象(通过调用 .execute()
)返回的响应是标准 Response
类的子类,它添加了一个名为 facets
的属性,该属性包含一个字典,其中包含桶列表 - 每个桶都由一个键、文档计数和一个标志表示,该标志指示该值是否已被过滤。
示例
from datetime import date
from elasticsearch_dsl import FacetedSearch, TermsFacet, DateHistogramFacet
class BlogSearch(FacetedSearch):
doc_types = [Article, ]
# fields that should be searched
fields = ['tags', 'title', 'body']
facets = {
# use bucket aggregations to define facets
'tags': TermsFacet(field='tags'),
'publishing_frequency': DateHistogramFacet(field='published_from', interval='month')
}
def search(self):
# override methods to add custom pieces
s = super().search()
return s.filter('range', publish_from={'lte': 'now/h'})
bs = BlogSearch('python web', {'publishing_frequency': date(2015, 6)})
response = bs.execute()
# access hits and other attributes as usual
total = response.hits.total
print('total hits', total.relation, total.value)
for hit in response:
print(hit.meta.score, hit.title)
for (tag, count, selected) in response.facets.tags:
print(tag, ' (SELECTED):' if selected else ':', count)
for (month, count, selected) in response.facets.publishing_frequency:
print(month.strftime('%B %Y'), ' (SELECTED):' if selected else ':', count)