我使用django-elasticsearch-dsl,但我遇到的问题是聚合总是向我返回空值。
我需要搜索结果的所有不同发布者和不同作者。
文档:
@registry.register_document
class BookDocument(Document):
author = fields.ObjectField(properties={
'name': fields.TextField(),'name_reverse': fields.TextField(),'pk': fields.IntegerField(),'slug': fields.TextField(),})
editorial = fields.nestedField(properties={
'name': fields.TextField(),},include_in_root=True)
class Index:
name = 'books'
settings = {'number_of_shards': 1,'number_of_replicas': 0}
class Django:
model = Book
fields = [
'title','isbn',]
related_models = [Author,Editorial] # para asegurarnos que cuando se actualice un author,se reindexa los libros
def get_queryset(self):
"""Not mandatory but to improve performance we can select related in one sql request"""
return super(BookDocument,self).get_queryset().select_related(
'author','editorial'
)
def get_instances_from_related(self,related_instance):
"""If related_models is set,define how to retrieve the Book instance(s) from the related model.
The related_models option should be used with caution because it can lead in the index
to the updating of a lot of items.
"""
if isinstance(related_instance,Author):
return related_instance.book_set.all()
elif isinstance(related_instance,Editorial):
return related_instance.book_set.all()
搜索:
from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search
from elasticsearch_dsl import Q
from elasticsearch_dsl.query import MultiMatch,Match
from elasticsearch_dsl import A
s = Search(index='books')
s = s.query("match",title="SECRET")
s = s[0:20]
s = s.highlight('title')
s.aggs.bucket('by_editorial','nested',path='editorial')\
.metric('max_lines','max',field='lines')
response = s.execute()
print(response.aggregations)
for item in response.aggregations.by_editorial.buckets:
print(item)
或者:
s = Search(index='books')
a = A('terms',field='author')
s.aggs.bucket('by_author',a)
response = s.execute()
print(response.aggregations)
for item in response.aggregations.by_author.buckets:
print(item)
我在做什么错?具有弹性的数据是正确的。
非常感谢您!
编辑:
我找到了一种解决问题的方法,以聚合方式获取对象的所有数据:
在模型中:
@property
def agg_data(self):
return 'id##{}~~name##{}~~slug##{}'.format(self.pk,self.name,self.slug)
在文档中:
editorial = fields.ObjectField(properties={
'name': fields.TextField(),'agg_data': fields.TextField(
analyzer=html_strip,fields={'raw': fields.KeywordField()}
),})
查询:
s = Search(index='books')
s = s.query("match",title="SECRET")
s.aggs.bucket('by_editorial','terms',field='editorial.agg_data.raw')
response = s.execute()
获得聚合结果后,我将解析该字段以将搜索过滤器安装到网络上。