def search_suggestions(request, lang, version, per_page=20): """ The endpoint for the OpenSearch browser integration. This will do a simple prefix match against the title to catch documents with a meaningful title. The link list contains redirect URLs so that IE will correctly redirect to those documents. """ try: release = DocumentRelease.objects.get_by_version_and_lang( version, lang) except DocumentRelease.DoesNotExist: raise Http404 form = DocSearchForm(request.GET or None, release=release) suggestions = [] if form.is_valid(): q = form.cleaned_data.get('q') if q: search = DocumentDocType.search() search = (search.query( query.SimpleQueryString( fields=['title^10', 'content'], query=q, analyzer='stop', default_operator='and')).filter( 'term', release__lang=release.lang).filter( 'term', release__version=release.version).source( includes=['title'])) suggestions.append(q) titles = [] links = [] content_type = ContentType.objects.get_for_model(Document) results = search[0:per_page].execute() for result in results: titles.append(result.title) kwargs = { 'content_type_id': content_type.pk, 'object_id': result.meta.id, } links.append(reverse('contenttypes-shortcut', kwargs=kwargs)) suggestions.append(titles) suggestions.append([]) suggestions.append(links) return JsonResponse(suggestions, safe=False)
def search_results(request, lang, version, per_page=10, orphans=3): """ Search view to handle language and version specific queries. The old search view is being redirected here. """ try: release = DocumentRelease.objects.get_by_version_and_lang( version, lang) except DocumentRelease.DoesNotExist: raise Http404 form = DocSearchForm(request.GET or None, release=release) context = { 'form': form, 'lang': release.lang, 'version': release.version, 'release': release, 'searchparams': request.GET.urlencode(), } if form.is_valid(): q = form.cleaned_data.get('q') if q: # catch queries that are coming from browser search bars exact = (DocumentDocType.index_queryset().filter(release=release, title=q).first()) if exact is not None: return redirect(exact) # let's just use simple queries since they allow some # neat syntaxes for exclusion etc. For more info see # http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html should = [ query.Common(_all={ 'query': q, 'cutoff_frequency': 0.001 }), query.SimpleQueryString(fields=['title', '_all'], query=q, default_operator='and'), ] # then apply the queries and filter out anything not matching # the wanted version and language, also highlight the content # and order the highlighted snippets by score so that the most # fitting result is used results = (DocumentDocType.search().query( query.Bool(should=should)).filter( 'term', release__lang=release.lang).filter( 'term', release__version=release.version).highlight_options( order='score').highlight('content_raw').extra( min_score=.01)) page_number = request.GET.get('page') or 1 paginator = SearchPaginator(results, per_page=per_page, orphans=orphans) try: page_number = int(page_number) except ValueError: if page_number == 'last': page_number = paginator.num_pages else: raise Http404( _("Page is not 'last', " "nor can it be converted to an int.")) try: page = paginator.page(page_number) except InvalidPage as e: raise Http404( _('Invalid page (%(page_number)s): %(message)s') % { 'page_number': page_number, 'message': str(e) }) context.update({ 'query': q, 'page': page, 'paginator': paginator, }) if release.lang != 'en': activate(release.lang) return render(request, 'docs/search_results.html', context)
def search_results(request, lang, version, per_page=10, orphans=3): """ Search view to handle language and version specific queries. The old search view is being redirected here. """ release = get_object_or_404(DocumentRelease, version=version, lang=lang) form = DocSearchForm(request.GET or None, release=release) context = { 'form': form, 'lang': release.lang, 'version': release.version, 'release': release, 'searchparams': request.GET.urlencode(), 'version_is_dev': version == 'dev', 'version_is_unsupported': version_is_unsupported(version), } if form.is_valid(): q = form.cleaned_data.get('q') if q: # catch queries that are coming from browser search bars exact = (DocumentDocType.index_queryset() .filter(release=release, title=q) .first()) if exact is not None: return redirect(exact) should = [] if any(operator in q for operator in SIMPLE_SEARCH_OPERATORS): should.append(query.SimpleQueryString(fields=['title', 'content^5'], query=q, analyzer='stop', default_operator='and')) else: # let's just use simple queries since they allow some # neat syntaxes for exclusion etc. For more info see # http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html should = [query.MultiMatch(fields=['title^10', 'content'], query=q, type='phrase_prefix'), query.Match(query=q), query.MultiMatch(fields=['title^5', 'content'], query=q, fuzziness=1)] # then apply the queries and filter out anything not matching # the wanted version and language, also highlight the content # and order the highlighted snippets by score so that the most # fitting result is used results = (DocumentDocType.search() .query(query.Bool(should=should)) .filter('term', release__lang=release.lang) .filter('term', release__version=release.version) .highlight_options(order='score') .highlight('content')) page_number = request.GET.get('page') or 1 paginator = SearchPaginator(results, per_page=per_page, orphans=orphans) try: page_number = int(page_number) except ValueError: if page_number == 'last': page_number = paginator.num_pages else: raise Http404(_("Page is not 'last', " "nor can it be converted to an int.")) try: page = paginator.page(page_number) except InvalidPage as e: raise Http404(_('Invalid page (%(page_number)s): %(message)s') % { 'page_number': page_number, 'message': str(e) }) context.update({ 'query': q, 'page': page, 'paginator': paginator, }) if release.lang != 'en': activate(release.lang) return render(request, 'docs/search_results.html', context)