def __init__(self, filter_json, request): self.request = request self.filter = filter_json self.query = { "sort": [ {"updated": {"order": "desc"}} ], "query": { "bool": { "minimum_number_should_match": 1}}} self.filter_scripts_to_add = [] if len(self.filter['clauses']): clauses = self.convert_clauses(self.filter['clauses']) # apply match policy policy = getattr(self, self.filter['match_policy']) policy(self.query['query']['bool'], clauses) else: self.query['query'] = {"match_all": {}} if len(self.filter_scripts_to_add): if 'filter' not in self.query: self.query['filter'] = {} scripts = ' AND '.join(self.filter_scripts_to_add) self.query['filter']['script'] = '"script": ' + scripts self.query["query"] = { "filtered": { "filter": nipsa.nipsa_filter( userid=request.authenticated_userid), "query": self.query["query"] } }
def search(request, params): """ Search with the given params and return the matching annotations. :param request: the request object :type request: pyramid.request.Request :param params: the search parameters :type params: dict-like :returns: a dict with keys "rows" (the list of matching annotations, as dicts) and "total" (the number of matching annotations, an int) :rtype: dict """ builder = query.Builder() builder.append_filter(query.AuthFilter(request)) builder.append_filter(query.UriFilter(request)) builder.append_filter(lambda _: \ nipsa.nipsa_filter(request.authenticated_userid)) builder.append_filter(query.GroupFilter(request)) builder.append_matcher(query.AnyMatcher()) builder.append_matcher(query.TagsMatcher()) body = builder.build(params) results = models.Annotation.search_raw(body, raw_result=True, authorization_enabled=False) total = results['hits']['total'] docs = results['hits']['hits'] rows = [models.Annotation(d['_source'], id=d['_id']) for d in docs] return {"rows": rows, "total": total}
def make_builder(): builder = query.Builder() builder.append_filter(query.AuthFilter(request, private=private)) builder.append_filter(query.UriFilter()) builder.append_filter( lambda _: nipsa.nipsa_filter(request.authenticated_userid)) builder.append_filter(query.GroupFilter()) builder.append_matcher(query.AnyMatcher()) builder.append_matcher(query.TagsMatcher()) return builder
def build_query(request_params, userid=None): """Return an Elasticsearch query dict for the given h search API params. Translates the HTTP request params accepted by the h search API into an Elasticsearch query dict. :param request_params: the HTTP request params that were posted to the h search API :type request_params: webob.multidict.NestedMultiDict :param userid: the ID of the authorized user (optional, default: None), :type userid: unicode or None :returns: an Elasticsearch query dict corresponding to the given h search API params :rtype: dict """ # NestedMultiDict objects are read-only, so we need to copy to make it # modifiable. request_params = request_params.copy() try: from_ = int(request_params.pop("offset")) if from_ < 0: raise ValueError except (ValueError, KeyError): from_ = 0 try: size = int(request_params.pop("limit")) if size < 0: raise ValueError except (ValueError, KeyError): size = 20 query = { "from": from_, "size": size, "sort": [ { request_params.pop("sort", "updated"): { "ignore_unmapped": True, "order": request_params.pop("order", "desc") } } ] } matches = [] uri_match_clause = _match_clause_for_uri(request_params.pop("uri", None)) if uri_match_clause: matches.append(uri_match_clause) if "any" in request_params: matches.append({ "multi_match": { "fields": ["quote", "tags", "text", "uri.parts", "user"], "query": request_params.getall("any"), "type": "cross_fields" } }) del request_params["any"] for key, value in request_params.items(): matches.append({"match": {key: value}}) matches = matches or [{"match_all": {}}] query["query"] = {"bool": {"must": matches}} query["query"] = { "filtered": { "filter": nipsa.nipsa_filter(userid=userid), "query": query["query"] } } return query
def build(request_params, userid=None, search_normalized_uris=False): """ Return an Elasticsearch query dict for the given h search API params. Translates the HTTP request params accepted by the h search API into an Elasticsearch query dict. :param request_params: the HTTP request params that were posted to the h search API :type request_params: webob.multidict.NestedMultiDict :param userid: the ID of the authorized user (optional, default: None), :type userid: unicode or None :param search_normalized_uris: Whether or not to use the "uri" param to search against pre-normalized URI fields. :type search_normalized_uris: bool :returns: an Elasticsearch query dict corresponding to the given h search API params :rtype: dict """ # NestedMultiDict objects are read-only, so we need to copy to make it # modifiable. request_params = request_params.copy() try: from_ = int(request_params.pop("offset")) if from_ < 0: raise ValueError except (ValueError, KeyError): from_ = 0 try: size = int(request_params.pop("limit")) if size < 0: raise ValueError except (ValueError, KeyError): size = 20 sort = [{ request_params.pop("sort", "updated"): { "ignore_unmapped": True, "order": request_params.pop("order", "desc") } }] filters = [] matches = [] uri_param = request_params.pop("uri", None) if uri_param is None: pass elif search_normalized_uris: filters.append(_term_clause_for_uri(uri_param)) else: matches.append(_match_clause_for_uri(uri_param)) if "any" in request_params: matches.append({ "multi_match": { "fields": ["quote", "tags", "text", "uri.parts", "user"], "query": request_params.getall("any"), "type": "cross_fields" } }) del request_params["any"] for key, value in request_params.items(): matches.append({"match": {key: value}}) # Add a filter for "not in public site areas" considerations filters.append(nipsa.nipsa_filter(userid=userid)) query = {"match_all": {}} if matches: query = {"bool": {"must": matches}} if filters: query = { "filtered": { "filter": {"and": filters}, "query": query, } } return { "from": from_, "size": size, "sort": sort, "query": query, }
def build(request_params, userid=None, search_normalized_uris=False): """ Return an Elasticsearch query dict for the given h search API params. Translates the HTTP request params accepted by the h search API into an Elasticsearch query dict. :param request_params: the HTTP request params that were posted to the h search API :type request_params: webob.multidict.NestedMultiDict :param userid: the ID of the authorized user (optional, default: None), :type userid: unicode or None :param search_normalized_uris: Whether or not to use the "uri" param to search against pre-normalized URI fields. :type search_normalized_uris: bool :returns: an Elasticsearch query dict corresponding to the given h search API params :rtype: dict """ # NestedMultiDict objects are read-only, so we need to copy to make it # modifiable. request_params = request_params.copy() try: from_ = int(request_params.pop("offset")) if from_ < 0: raise ValueError except (ValueError, KeyError): from_ = 0 try: size = int(request_params.pop("limit")) if size < 0: raise ValueError except (ValueError, KeyError): size = 20 sort = [{ request_params.pop("sort", "updated"): { "ignore_unmapped": True, "order": request_params.pop("order", "desc") } }] filters = [] matches = [] uri_param = request_params.pop("uri", None) if uri_param is None: pass elif search_normalized_uris: filters.append(_term_clause_for_uri(uri_param)) else: matches.append(_match_clause_for_uri(uri_param)) if "any" in request_params: matches.append({ "multi_match": { "fields": ["quote", "tags", "text", "uri.parts", "user"], "query": request_params.getall("any"), "type": "cross_fields" } }) del request_params["any"] for key, value in request_params.items(): matches.append({"match": {key: value}}) # Add a filter for "not in public site areas" considerations filters.append(nipsa.nipsa_filter(userid=userid)) query = {"match_all": {}} if matches: query = {"bool": {"must": matches}} if filters: query = { "filtered": { "filter": { "and": filters }, "query": query, } } return { "from": from_, "size": size, "sort": sort, "query": query, }