def _document_suggestions(searcher, text, locale, product, max_results): if max_results <= 0: return [] search_filter = es_utils.F( model='wiki_document', document_category__in=settings.SEARCH_DEFAULT_CATEGORIES, document_locale=locale, document_is_archived=False) if product: search_filter &= es_utils.F(product=product) documents = [] searcher = _query(searcher, DocumentMappingType, search_filter, text, locale) doc_ids = [result['id'] for result in searcher[:max_results]] documents = [ DocumentDetailSerializer(instance=doc).data for doc in Document.objects.filter(id__in=doc_ids) ] return documents
def _document_suggestions(searcher, text, locale, product, max_results): if max_results <= 0: return [] search_filter = es_utils.F( model='wiki_document', document_category__in=settings.SEARCH_DEFAULT_CATEGORIES, document_locale=locale, document_is_archived=False) if product is not None: search_filter &= es_utils.F(product=product) documents = [] searcher = _query(searcher, DocumentMappingType, search_filter, text, locale) for result in searcher[:max_results]: documents.append({ 'title': result['document_title'], 'slug': result['document_slug'], 'summary': result['document_summary'], 'url': result['url'], }) return documents
def _question_suggestions(searcher, text, locale, product, max_results): if max_results <= 0: return [] search_filter = es_utils.F( model="questions_question", question_is_archived=False, question_is_locked=False, question_is_solved=True, ) if product: search_filter &= es_utils.F(product=product) if locale: search_filter &= es_utils.F(question_locale=locale) questions = [] searcher = _query(searcher, QuestionMappingType, search_filter, text, locale) question_ids = [result["id"] for result in searcher[:max_results]] questions = [ QuestionSerializer(instance=q).data for q in Question.objects.filter(id__in=question_ids) ] return questions
def get_filters(self, form_cleaned): question_f = es_utils.F(model='questions_question') # Product filter products = form_cleaned['product'] for p in products: question_f &= es_utils.F(product=p) # Topics filter topics = form_cleaned['topics'] for t in topics: question_f &= es_utils.F(topic=t) return question_f
def get_filters(self, form_cleaned): wiki_f = es_utils.F(model='wiki_document') if form_cleaned['category']: wiki_f &= es_utils.F( document_category__in=form_cleaned['category']) # Locale filter wiki_f &= es_utils.F(document_locale=self.language) # Product filter products = form_cleaned['product'] for p in products: wiki_f &= es_utils.F(product=p) # Topics filter topics = form_cleaned['topics'] for t in topics: wiki_f &= es_utils.F(topic=t) return wiki_f
def _question_suggestions(searcher, text, locale, product, max_results): if max_results <= 0: return [] search_filter = es_utils.F(model='questions_question', question_is_archived=False, question_is_locked=False, question_is_solved=True) if product is not None: search_filter &= es_utils.F(product=product) questions = [] searcher = _query(searcher, QuestionMappingType, search_filter, text, locale) for result in searcher[:max_results]: q = Question.objects.get(id=result['id']) questions.append(QuestionSerializer(instance=q).data) return questions
def suggest(request): text = request.body or request.GET.get('q') locale = request.GET.get('locale', settings.WIKI_DEFAULT_LANGUAGE) product = request.GET.get('product') max_questions = request.GET.get('max_questions', 10) max_documents = request.GET.get('max_documents', 10) errors = {} try: max_questions = int(max_questions) except ValueError: errors['max_questions'] = 'This field must be an integer.' try: max_documents = int(max_documents) except ValueError: errors['max_documents'] = 'This field must be an integer.' if text is None: errors['q'] = 'This field is required.' if product is not None and not Product.objects.filter( slug=product).exists(): errors['product'] = 'Could not find product with slug "{0}".'.format( product) if errors: raise GenericAPIException(400, errors) wiki_f = es_utils.F( model='wiki_document', document_category__in=settings.SEARCH_DEFAULT_CATEGORIES, document_locale=locale, document_is_archived=False) questions_f = es_utils.F(model='questions_question', question_is_archived=False, question_is_locked=False, question_has_helpful=True) if product is not None: wiki_f &= es_utils.F(product=product) questions_f &= es_utils.F(product=product) mapping_types = [QuestionMappingType, DocumentMappingType] query_fields = itertools.chain( *[cls.get_query_fields() for cls in mapping_types]) query = {} for field in query_fields: for query_type in ['match', 'match_phrase']: key = '{0}__{1}'.format(field, query_type) query[key] = text # Transform query to be locale aware. query = es_utils.es_query_with_analyzer(query, locale) searcher = (es_utils.AnalyzerS().es(urls=settings.ES_URLS).indexes( es_utils.read_index('default')).doctypes( *[cls.get_mapping_type_name() for cls in mapping_types]).filter(wiki_f | questions_f).query( should=True, **query)) documents = [] questions = [] for result in searcher[:(max_documents + max_questions) * 2]: if result['model'] == 'wiki_document': documents.append({ 'title': result['document_title'], 'slug': result['document_slug'], 'summary': result['document_summary'], }) elif result['model'] == 'questions_question': questions.append({ 'id': result['id'], 'title': result['question_title'], }) if len(documents) >= max_documents and len(questions) >= max_questions: break return Response({ 'questions': questions[:max_questions], 'documents': documents[:max_documents], })
def generate_simple_search(search_form, language, with_highlights=False): """Generates an S given a form :arg search_form: a validated SimpleSearch form :arg language: the language code :arg with_highlights: whether or not to ask for highlights :returns: a fully formed S """ # We use a regular S here because we want to search across # multiple doctypes. searcher = (es_utils.AnalyzerS().es( urls=settings.ES_URLS, timeout=settings.ES_TIMEOUT, use_ssl=settings.ES_USE_SSL, http_auth=settings.ES_HTTP_AUTH, connection_class=RequestsHttpConnection, ).indexes(es_utils.read_index("default"))) cleaned = search_form.cleaned_data doctypes = [] final_filter = es_utils.F() cleaned_q = cleaned["q"] products = cleaned["product"] # Handle wiki filters if cleaned["w"] & constants.WHERE_WIKI: wiki_f = es_utils.F( model="wiki_document", document_category__in=settings.SEARCH_DEFAULT_CATEGORIES, document_locale=language, document_is_archived=False, ) for p in products: wiki_f &= es_utils.F(product=p) doctypes.append(DocumentMappingType.get_mapping_type_name()) final_filter |= wiki_f # Handle question filters if cleaned["w"] & constants.WHERE_SUPPORT: question_f = es_utils.F(model="questions_question", question_is_archived=False, question_has_helpful=True) for p in products: question_f &= es_utils.F(product=p) doctypes.append(QuestionMappingType.get_mapping_type_name()) final_filter |= question_f # Build a filter for those filters and add the other bits to # finish the search searcher = searcher.doctypes(*doctypes) searcher = searcher.filter(final_filter) if cleaned["explain"]: searcher = searcher.explain() if with_highlights: # Set up the highlights. Show the entire field highlighted. searcher = searcher.highlight( "question_content", # support forum "document_summary", # kb pre_tags=["<b>"], post_tags=["</b>"], number_of_fragments=0, ) searcher = apply_boosts(searcher) # Build the query query_fields = chain(*[ cls.get_query_fields() for cls in [DocumentMappingType, QuestionMappingType] ]) query = {} # Create match and match_phrase queries for every field # we want to search. for field in query_fields: for query_type in ["match", "match_phrase"]: query["%s__%s" % (field, query_type)] = cleaned_q # Transform the query to use locale aware analyzers. query = es_utils.es_query_with_analyzer(query, language) searcher = searcher.query(should=True, **query) return searcher
def get_filters(self): return es_utils.F()
def get_filters(self, form_cleaned): return es_utils.F()