Пример #1
0
def VideohubChannel(included_ids=None, excluded_ids=None):
    f = MatchAll()
    if included_ids:
        f &= Nested(path="videohub_ref",
                    filter=Terms(**{"videohub_ref.channel_id": included_ids}))
    if excluded_ids:
        f &= ~Nested(path="videohub_ref",
                     filter=Terms(**{"videohub_ref.channel_id": excluded_ids}))
Пример #2
0
def Authors(usernames):  # noqa
    included, excluded = _parse_slugs(usernames)

    f = MatchAll()
    if included:
        f &= Terms(**{"authors.username": included})
    if excluded:
        f &= Terms(**{"authors.username": excluded})
    return f
Пример #3
0
def Tags(slugs):  # noqa
    included, excluded = _parse_slugs(slugs)

    f = MatchAll()
    if included:
        f &= Nested(path="tags", filter=Terms(**{"tags.slug": included}))
    if excluded:
        f &= ~Nested(path="tags", filter=Terms(**{"tags.slug": excluded}))

    return f
Пример #4
0
def FeatureTypes(slugs):  # noqa
    included, excluded = _parse_slugs(slugs)

    f = MatchAll()
    if included:
        f &= Nested(path="feature_type",
                    filter=Terms(**{"feature_type.slug": included}))
    if excluded:
        f &= ~Nested(path="feature_type",
                     filter=Terms(**{"feature_type.slug": excluded}))

    return f
Пример #5
0
def preview_filter_from_query(query, id_field="id", field_map={}):
    """This filter includes the "excluded_ids" so they still show up in the editor."""
    f = groups_filter_from_query(query, field_map=field_map)
    # NOTE: we don't exclude the excluded ids here so they show up in the editor
    # include these, please
    included_ids = query.get("included_ids")
    if included_ids:
        if f:
            f |= Terms(pk=included_ids)
        else:
            f = Terms(pk=included_ids)
    return f
Пример #6
0
def groups_filter_from_query(query, field_map={}):
    """Creates an F object for the groups of a search query."""
    f = None
    # filter groups
    for group in query.get("groups", []):
        group_f = MatchAll()
        for condition in group.get("conditions", []):
            field_name = condition["field"]
            field_name = field_map.get(field_name, field_name)
            operation = condition["type"]
            values = condition["values"]
            if values:
                values = [v["value"] for v in values]
                if operation == "all":
                    # NOTE: is there a better way to express this?
                    for value in values:
                        if "." in field_name:
                            path = field_name.split(".")[0]
                            group_f &= Nested(
                                path=path, filter=Term(**{field_name: value}))
                        else:
                            group_f &= Term(**{field_name: value})
                elif operation == "any":
                    if "." in field_name:
                        path = field_name.split(".")[0]
                        group_f &= Nested(path=path,
                                          filter=Terms(**{field_name: values}))
                    else:
                        group_f &= Terms(**{field_name: values})
                elif operation == "none":
                    if "." in field_name:
                        path = field_name.split(".")[0]
                        group_f &= ~Nested(
                            path=path, filter=Terms(**{field_name: values}))
                    else:
                        group_f &= ~Terms(**{field_name: values})

        date_range = group.get("time")
        if date_range:
            group_f &= date_range_filter(date_range)
        if f:
            f |= group_f
        else:
            f = group_f
    return f
Пример #7
0
def TagBoost(slugs, boost_mode="multiply", weight=5):
    included, excluded = _parse_slugs(slugs)
    return FunctionScore(boost_mode=boost_mode,
                         functions=[{
                             "filter":
                             Nested(path="tags",
                                    filter=Terms(**{"tags.slug": included})),
                             "weight":
                             weight
                         }])
Пример #8
0
def get_condition_filter(condition, field_map={}):
    """
    Return the appropriate filter for a given group condition.

    #  TODO: integrate this into groups_filter_from_query function.
    """
    field_name = condition.get("field")
    field_name = field_map.get(field_name, field_name)
    operation = condition["type"]
    values = condition["values"]

    condition_filter = MatchAll()

    if values:
        values = [v["value"] for v in values]
        if operation == "all":
            for value in values:
                if "." in field_name:
                    path = field_name.split(".")[0]
                    condition_filter &= Nested(
                        path=path, filter=Term(**{field_name: value}))
                else:
                    condition_filter &= Term(**{field_name: value})
        elif operation == "any":
            if "." in field_name:
                path = field_name.split(".")[0]
                condition_filter &= Nested(
                    path=path, filter=Terms(**{field_name: values}))
            else:
                condition_filter &= Terms(**{field_name: values})
        elif operation == "none":
            if "." in field_name:
                path = field_name.split(".")[0]
                condition_filter &= ~Nested(
                    path=path, filter=Terms(**{field_name: values}))
            else:
                condition_filter &= ~Terms(**{field_name: values})
        else:
            raise ValueError(
                """ES conditions must be one of the following values: ['all', 'any', 'none']"""
            )
    return condition_filter
Пример #9
0
def filter_from_query(query, id_field="id", field_map={}):
    """This returns a filter which actually filters out everything, unlike the
    preview filter which includes excluded_ids for UI purposes.
    """
    f = groups_filter_from_query(query, field_map=field_map)
    excluded_ids = query.get("excluded_ids")
    included_ids = query.get("included_ids")

    if included_ids:  # include these, please
        if f is None:
            f = Terms(pk=included_ids)
        else:
            f |= Terms(pk=included_ids)

    if excluded_ids:  # exclude these
        if f is None:
            f = MatchAll()

        f &= ~Terms(pk=excluded_ids)
    return f
Пример #10
0
def custom_search_model(model,
                        query,
                        preview=False,
                        published=False,
                        id_field="id",
                        sort_pinned=True,
                        field_map={}):
    """Filter a model with the given filter.

    `field_map` translates incoming field names to the appropriate ES names.
    """
    if preview:
        func = preview_filter_from_query
    else:
        func = filter_from_query
    f = func(query, id_field=id_field, field_map=field_map)
    # filter by published
    if published:
        if f:
            f &= Range(published={"lte": timezone.now()})
        else:
            f = Range(published={"lte": timezone.now()})

    qs = model.search_objects.search(published=False)
    if f:
        qs = qs.filter(f)

    # possibly include a text query
    if query.get("query"):
        qs = qs.query("match", _all=query["query"])
    # set up pinned ids
    pinned_ids = query.get("pinned_ids")
    if pinned_ids and sort_pinned:

        pinned_query = es_query.FunctionScore(boost_mode="multiply",
                                              functions=[{
                                                  "filter":
                                                  Terms(id=pinned_ids),
                                                  "weight":
                                                  2
                                              }])

        qs = qs.query(pinned_query)
        qs = qs.sort("_score", "-published")
    else:
        qs = qs.sort("-published")
    return qs