Я использую django -asticsearch-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(),
'slug': fields.TextField(),
'pk': fields.IntegerField(),
}, 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(),
'slug': fields.TextField(),
'pk': fields.IntegerField(),
'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()
Когда ячтобы получить результаты агрегации, я разбираю поле для подключения поисковых фильтров в сети.