Beispiel #1
0
    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"]
            }
        }
Beispiel #2
0
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}
Beispiel #3
0
Datei: core.py Projekt: JJediny/h
 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
Beispiel #4
0
 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
Beispiel #5
0
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
Beispiel #6
0
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,
    }
Beispiel #7
0
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,
    }