Skip to content

Commit 2888d2e

Browse files
authored
Merge pull request #5950 from dojutsu-user/fix--invalid-highlight-search
Hotfix: Return empty dict when no highlight dict is present
2 parents fda7fc3 + c0a5fd9 commit 2888d2e

File tree

3 files changed

+25
-61
lines changed

3 files changed

+25
-61
lines changed

readthedocs/search/api.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import itertools
22
import logging
3-
from operator import attrgetter
4-
from pprint import pformat
53

64
from rest_framework import generics, serializers
75
from rest_framework.exceptions import ValidationError
@@ -38,8 +36,8 @@ def get_link(self, obj):
3836
def get_highlight(self, obj):
3937
highlight = getattr(obj.meta, 'highlight', None)
4038
if highlight:
41-
ret = utils._remove_newlines_from_dict(highlight.to_dict())
42-
log.debug('API Search highlight [Page title]: %s', pformat(ret))
39+
ret = highlight.to_dict()
40+
log.debug('API Search highlight [Page title]: %s', ret)
4341
return ret
4442

4543
def get_inner_hits(self, obj):
@@ -49,27 +47,13 @@ def get_inner_hits(self, obj):
4947
domains = inner_hits.domains or []
5048
all_results = itertools.chain(sections, domains)
5149

52-
sorted_results = [
53-
{
54-
'type': hit._nested.field,
55-
'_source': hit._source.to_dict(),
56-
'highlight': self._get_inner_hits_highlights(hit),
57-
}
58-
for hit in sorted(all_results, key=attrgetter('_score'), reverse=True)
59-
]
60-
61-
return sorted_results
62-
63-
def _get_inner_hits_highlights(self, hit):
64-
"""Removes new lines from highlight and log it."""
65-
if hasattr(hit, 'highlight'):
66-
highlight_dict = utils._remove_newlines_from_dict(
67-
hit.highlight.to_dict()
50+
sorted_results = utils._get_sorted_results(
51+
results=all_results,
52+
source_key='_source',
6853
)
6954

70-
log.debug('API Search highlight: %s', pformat(highlight_dict))
71-
return highlight_dict
72-
return {}
55+
log.debug('[API] Sorted Results: %s', sorted_results)
56+
return sorted_results
7357

7458

7559
class PageSearchAPIView(generics.ListAPIView):

readthedocs/search/utils.py

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Utilities related to reading and generating indexable search content."""
22

33
import logging
4+
from operator import attrgetter
45

56
from django.shortcuts import get_object_or_404
67
from django_elasticsearch_dsl.apps import DEDConfig
@@ -153,24 +154,15 @@ def _indexing_helper(html_objs_qs, wipe=False):
153154
delete_objects_in_es.delay(**kwargs)
154155

155156

156-
def _remove_newlines_from_dict(highlight):
157-
"""
158-
Recursively change results to turn newlines into periods.
157+
def _get_sorted_results(results, source_key='_source'):
158+
"""Sort results according to their score and returns results as list."""
159+
sorted_results = [
160+
{
161+
'type': hit._nested.field,
162+
source_key: hit._source.to_dict(),
163+
'highlight': hit.highlight.to_dict() if hasattr(hit, 'highlight') else {}
164+
}
165+
for hit in sorted(results, key=attrgetter('_score'), reverse=True)
166+
]
159167

160-
See: https://github.com/rtfd/readthedocs.org/issues/5168
161-
:param highlight: highlight dict whose contents are to be edited.
162-
:type highlight: dict
163-
:returns: dict with all the newlines changed to periods.
164-
:rtype: dict
165-
"""
166-
for k, v in highlight.items():
167-
if isinstance(v, dict):
168-
highlight[k] = _remove_newlines_from_dict(v)
169-
else:
170-
# elastic returns the contents of the
171-
# highlighted field in a list.
172-
if isinstance(v, list):
173-
v_new_list = [res.replace('\n', '. ') for res in v]
174-
highlight[k] = v_new_list
175-
176-
return highlight
168+
return sorted_results

readthedocs/search/views.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import itertools
44
import logging
55
from operator import attrgetter
6-
from pprint import pformat
76

87
from django.shortcuts import get_object_or_404, render
98

@@ -117,28 +116,17 @@ def elastic_search(request, project_slug=None):
117116
domains = inner_hits.domains or []
118117
all_results = itertools.chain(sections, domains)
119118

120-
sorted_results = [
121-
{
122-
'type': hit._nested.field,
123-
124-
# here _source term is not used because
125-
# django gives error if the names of the
126-
# variables start with underscore
127-
'source': hit._source.to_dict(),
128-
129-
'highlight': utils._remove_newlines_from_dict(
130-
hit.highlight.to_dict()
131-
),
132-
}
133-
for hit in sorted(all_results, key=attrgetter('_score'), reverse=True)
134-
]
119+
sorted_results = utils._get_sorted_results(
120+
results=all_results,
121+
source_key='source',
122+
)
135123

136124
result.meta.inner_hits = sorted_results
137125
except Exception:
138126
log.exception('Error while sorting the results (inner_hits).')
139127

140-
log.debug('Search results: %s', pformat(results.to_dict()))
141-
log.debug('Search facets: %s', pformat(results.facets.to_dict()))
128+
log.debug('Search results: %s', results.to_dict())
129+
log.debug('Search facets: %s', results.facets.to_dict())
142130

143131
template_vars = user_input._asdict()
144132
template_vars.update({

0 commit comments

Comments
 (0)