def suggester(request): ''' Provide auto suggestions. Ajax request returning a JSON response. ''' query_dict = request.GET idx_dict = ElasticSettings.search_props(query_dict.get("idx"), request.user) suggester = ','.join(ElasticSettings.idx(k) for k in idx_dict['suggester_keys']) resp = Suggest.suggest(query_dict.get("term"), suggester, name='suggest', size=8)['suggest'] return JsonResponse({"data": [opts['text'] for opts in resp[0]['options']]})
def test_search_props(self): if 'pydgin_auth' in settings.INSTALLED_APPS: from pydgin_auth.elastic_model_factory import ElasticPermissionModelFactory from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import Group, User, Permission from django.shortcuts import get_object_or_404 ElasticPermissionModelFactory.create_dynamic_models() search_props = ElasticSettings.search_props("ALL") idx = search_props['idx'] idx_keys = search_props['idx_keys'] idx_type = search_props['idx_type'] self.assertIn('publications', idx, 'publications found in idx') self.assertIn('MARKER', idx_keys, 'MARKER found in idx_keys') self.assertIn('rs_merge', idx_type, 'rs_merge found in idx_type') # CREATE DIL group and add test_dil user to that group dil_group, created = Group.objects.get_or_create(name='DILX') self.assertTrue(created) dil_user = User.objects.create_user( username='******', email='*****@*****.**', password='******') dil_user.groups.add(dil_group) self.assertTrue(dil_user.groups.filter(name='DILX').exists()) # create permission for MARKER and IC test_model_name = 'marker-ic_idx_type' # create permissions on models and retest again to check if the idx type could be seen content_type, created = ContentType.objects.get_or_create( model=test_model_name, app_label="elastic", ) # get the permission ... already created can_read_permission = Permission.objects.get(content_type=content_type) self.assertEqual('can_read_marker-ic_idx_type', can_read_permission.codename, "idx type permission correct") # as soon as the permission is set for an index, the index becomes a restricted resource idx_types_visible = ElasticSettings.search_props("ALL")["idx_type"] self.assertFalse('immunochip' in idx_types_visible, 'immunochip idx type not visible') # now grant permission to dil_user and check if idx type is visible dil_group.permissions.add(can_read_permission) dil_user = get_object_or_404(User, pk=dil_user.id) idx_types_visible = ElasticSettings.search_props("ALL", dil_user)["idx_type"] self.assertTrue('immunochip' in idx_types_visible, 'immunochip idx type visible now')
def test_search_props(self): ''' Test call for search props. ''' self.assertJSONEqual( json.dumps(ElasticSettings.search_props()), json.dumps({ 'idx_keys': ['MARKER'], 'idx_type': 'marker', 'idx': 'dbsnp144', 'suggester_keys': ['MARKER'] }))
def _get_query_filters(q_dict, user): ''' Build query bool filter. If biotypes are specified add them to the filter and allow for other non-gene types. @type q_dict: dict @param q_dict: request dictionary. ''' if not q_dict.getlist("biotypes"): return None query_bool = BoolQuery() if q_dict.getlist("biotypes"): query_bool.should(Query.terms("biotype", q_dict.getlist("biotypes"))) type_filter = [Query.query_type_for_filter(ElasticSettings.search_props(c.upper(), user)['idx_type']) for c in q_dict.getlist("categories") if c != "gene"] if len(type_filter) > 0: query_bool.should(type_filter) return Filter(query_bool)
def _search_engine(query_dict, user_filters, user): ''' Carry out a search and add results to the context object. ''' user_query = query_dict.get("query") query = _gene_lookup(user_query) source_filter = [ 'symbol', 'synonyms', "dbxrefs.*", 'biotype', 'description', # gene 'id', 'rscurrent', 'rshigh', # marker 'journal', 'title', 'tags.disease', # publication 'name', 'code', # disease 'study_id', 'study_name', # study 'region_name', 'marker'] # regions if re.compile(r'^[0-9 ]+$').findall(query): source_filter.append('pmid') # publication - possible PMID(s) search_fields = [] maxsize = 20 if user_filters.getlist("maxsize"): maxsize = int(user_filters.get("maxsize")) # build search_fields from user input filter fields for it in user_filters.items(): if len(it) == 2: if it[0] == 'query': continue parts = it[1].split(":") if len(parts) == 3: search_fields.append(parts[1]+"."+parts[2]) elif len(parts) == 2: search_fields.append(parts[1]) if len(search_fields) == 0: search_fields = list(source_filter) search_fields.extend(['abstract', 'authors.name', # publication 'authors', 'pmids', # study 'markers', 'genes']) # study/region source_filter.extend(['date', 'pmid', 'build_id', 'ref', 'alt', 'chr_band', 'disease_locus', 'disease_loci', 'region_id']) idx_name = query_dict.get("idx") idx_dict = ElasticSettings.search_props(idx_name, user) query_filters = _get_query_filters(user_filters, user) highlight = Highlight(search_fields, pre_tags="<strong>", post_tags="</strong>", number_of_fragments=0) sub_agg = Agg('idx_top_hits', 'top_hits', {"size": maxsize, "_source": source_filter, "highlight": highlight.highlight['highlight']}) aggs = Aggs([Agg("idxs", "terms", {"field": "_index"}, sub_agg=sub_agg), Agg("biotypes", "terms", {"field": "biotype", "size": 0}), Agg("categories", "terms", {"field": "_type", "size": 0})]) # create score functions score_fns = _build_score_functions(idx_dict) equery = BoolQuery(must_arr=Query.query_string(query, fields=search_fields), should_arr=_auth_arr(user), b_filter=query_filters, minimum_should_match=1) search_query = ElasticQuery(FunctionScoreQuery(equery, score_fns, boost_mode='replace')) elastic = Search(search_query=search_query, aggs=aggs, size=0, idx=idx_dict['idx'], idx_type=idx_dict['idx_type']) result = elastic.search() mappings = elastic.get_mapping() _update_mapping_filters(mappings, result.aggs) _update_biotypes(user_filters, result) return {'data': _top_hits(result), 'aggs': result.aggs, 'query': user_query, 'idx_name': idx_name, 'fields': search_fields, 'mappings': mappings, 'hits_total': result.hits_total, 'maxsize': maxsize, 'took': result.took}
def search_keys(context): ''' Get the search index key names (e.g. MARKER, GENE). ''' return ElasticSettings.search_props(user=context['request'].user)['idx_keys']
def show_search_engine(context): ''' Template inclusion tag to render search engine form. ''' return {'index': ElasticSettings.search_props(user=context['request'].user)['idx_keys']}
def show_search_engine(context): """ Template inclusion tag to render search engine form. """ return {"index": ElasticSettings.search_props(user=context["request"].user)["idx_keys"]}