Files
Diarios-Oficiais-ALEMS/diarios/search_service.py

68 lines
2.1 KiB
Python
Raw Normal View History

from elasticsearch_dsl import Q, Search
from .documents import DiarioOficialDocument
class DiarioOficialSearchService:
@staticmethod
def search(query, highlight=True, fuzziness=1, page=1, page_size=10, tipos=None, data_inicio=None, data_fim=None):
# Configura a busca básica
s = DiarioOficialDocument.search().source(excludes=['page_content.content'])
# Filtros
if tipos:
s = s.filter('terms', tipo_nome=tipos)
if data_inicio and data_fim:
s = s.filter('range', data={'gte': data_inicio, 'lte': data_fim})
# Query principal com fuzziness e sinônimos
main_query = Q(
'multi_match',
query=query,
fields=[
'numero^3', # Maior peso para o número
'tipo_nome^2', # Peso médio para o tipo
'page_content.content' # Peso padrão para o conteúdo
],
fuzziness=fuzziness,
analyzer='portuguese_synonyms'
)
s = s.query(main_query)
# Highlighting
if highlight:
s = s.highlight(
'page_content.content',
fragment_size=150,
number_of_fragments=3,
pre_tags=['<mark>'],
post_tags=['</mark>']
)
# Paginação
start = (page - 1) * page_size
end = start + page_size
s = s[start:end]
# Executa a busca
response = s.execute()
# Formata os resultados
results = []
for hit in response:
result = {
'id': hit.id,
'numero': hit.numero,
'data': hit.data,
'link': hit.link,
'tipo_nome': hit.tipo_nome,
'score': hit.meta.score
}
if highlight and hasattr(hit.meta, 'highlight'):
result['highlights'] = hit.meta.highlight['page_content.content'].to_dict()
results.append(result)
return {
'total': response.hits.total.value,
'results': results
}