def test_create_filter_dsl():
    """Test request value extraction."""
    app = Flask('testapp')
    kwargs = MultiDict([('a', '1')])
    defs = dict(
        type=terms_filter('type.type'),
        subtype=terms_filter('type.subtype'),
    )

    with app.test_request_context(u'?type=a&type=b&subtype=c&type=zażółcić'):
        filters, args = _create_filter_dsl(kwargs, defs)
        assert len(filters) == 2
        assert args == MultiDict([
            ('a', u'1'),
            ('type', u'a'),
            ('type', u'b'),
            ('subtype', u'c'),
            ('type', u'zażółcić')
        ])

    kwargs = MultiDict([('a', '1')])
    with app.test_request_context('?atype=a&atype=b'):
        filters, args = _create_filter_dsl(kwargs, defs)
        assert not filters
        assert args == kwargs
def _aggregations(search, definitions, urlkwargs, filters):
    """Add aggregations to query."""
    def without(d, keys):
        """Remove keys from dict."""
        new_d = d.copy()
        for key in keys:
            new_d.pop(key)
        return new_d

    if definitions:
        for name, agg in definitions.items():

            # get nested aggs
            names = [name]
            names.extend(agg.get('aggs', {}).keys())

            # collect filters except for aggs or nested aggs ones
            _filters, _ = _create_filter_dsl(urlkwargs,
                                             without(filters, names))
            if _filters:
                agg = {
                    'filter': {
                        'bool': {
                            'must': [x.to_dict() for x in _filters]
                        }
                    },
                    'aggs': {
                        'filtered': agg
                    }
                }
            search.aggs[name] = agg
    return search
def _aggregations(search, definitions, urlkwargs, filters):
    """Add aggregations to query."""
    def without(d, keys):
        """Remove keys from dict."""
        new_d = d.copy()
        for key in keys:
            new_d.pop(key)
        return new_d

    if definitions:
        for name, agg in definitions.items():

            # get nested aggs
            names = [name]
            names.extend(agg.get('aggs', {}).keys())

            # collect filters except for aggs or nested aggs ones
            _filters, _ = _create_filter_dsl(urlkwargs,
                                             without(filters, names))
            if _filters:
                agg = {
                    'filter': {
                        'bool': {
                            'must': [x.to_dict() for x in _filters]
                        }
                    },
                    'aggs': {
                        'filtered': agg
                    }
                }
            search.aggs[name] = agg
    return search
Exemple #4
0
def _post_filter(search, urlkwargs, definitions):
    """Ingest post filter in query."""
    filters, urlkwargs = _create_filter_dsl(urlkwargs, definitions)

    for filter_ in filters:
        search = search.filter(filter_)

    return (search, urlkwargs)
Exemple #5
0
def test_create_filter_dsl():
    """Test request value extraction."""
    app = Flask('testapp')
    kwargs = MultiDict([('a', '1')])
    defs = dict(
        type=terms_filter('type.type'),
        subtype=terms_filter('type.subtype'),
    )

    with app.test_request_context("?type=a&type=b&subtype=c"):
        query, args = _create_filter_dsl(kwargs, defs)
        assert len(query['bool']['filter']) == 2
        assert args == MultiDict([('a', '1'), ('type', 'a'), ('type', 'b'),
                                  ('subtype', 'c')])

    kwargs = MultiDict([('a', '1')])
    with app.test_request_context("?atype=a&atype=b"):
        query, args = _create_filter_dsl(kwargs, defs)
        assert query is None
        assert args == kwargs
def test_create_filter_dsl():
    """Test request value extraction."""
    app = Flask('testapp')
    kwargs = MultiDict([('a', '1')])
    defs = dict(
        type=terms_filter('type.type'),
        subtype=terms_filter('type.subtype'),
    )

    with app.test_request_context(u'?type=a&type=b&subtype=c&type=zażółcić'):
        filters, args = _create_filter_dsl(kwargs, defs)
        assert len(filters) == 2
        assert args == MultiDict([('a', u'1'), ('type', u'a'), ('type', u'b'),
                                  ('subtype', u'c'), ('type', u'zażółcić')])

    kwargs = MultiDict([('a', '1')])
    with app.test_request_context('?atype=a&atype=b'):
        filters, args = _create_filter_dsl(kwargs, defs)
        assert not filters
        assert args == kwargs
Exemple #7
0
def _aggregations(search, definitions, urlkwargs, filters):
    """Add aggregations to query.

    :param search: Invenio Search Object
    :param definitions: Dictionary of all available facets definitions
    :param urlkwargs: Argument from the query
    :param filters: Filters applied on facets

    :return: Search object with custom filtered object in aggregation
             after every filter is applied.
    """

    def without_nested_subtypes(facet_filters, facet_names):
        """Remove the nested subtypes from the filter.

        Example: If `CMS` from Experiment type is selected
        then aggregation count of other subtypes in Experiment
        type will not be changed.
        """
        new_facet_filters = facet_filters.copy()
        for name in facet_names:
            new_facet_filters.pop(name)
        return new_facet_filters

    if definitions:
        for facet_name, aggregation in definitions.items():
            # get nested aggs
            facet_names = [facet_name]
            facet_names.extend(aggregation.get("aggs", {}).keys())

            # collect filters except for aggs and nested aggs (if any)
            facet_filters, _ = _create_filter_dsl(
                            urlkwargs,
                            without_nested_subtypes(
                                filters,
                                facet_names)
                        )
            if facet_filters:
                aggregation = {
                    "filter":
                        {
                            "bool":
                                {
                                    "must": [
                                            facet_filter.to_dict()
                                            for facet_filter in facet_filters
                                        ]
                                }
                        },
                    "aggs": {"filtered": aggregation},
                }
            search.aggs[facet_name] = aggregation
    return search
def test_create_filter_dsl():
    """Test request value extraction."""
    app = Flask('testapp')
    kwargs = MultiDict([('a', '1')])
    defs = dict(
        type=terms_filter('type.type'),
        subtype=terms_filter('type.subtype'),
    )

    with app.test_request_context("?type=a&type=b&subtype=c"):
        query, args = _create_filter_dsl(kwargs, defs)
        assert len(query['bool']['filter']) == 2
        assert args == MultiDict([
            ('a', '1'),
            ('type', 'a'),
            ('type', 'b'),
            ('subtype', 'c')
        ])

    kwargs = MultiDict([('a', '1')])
    with app.test_request_context("?atype=a&atype=b"):
        query, args = _create_filter_dsl(kwargs, defs)
        assert query is None
        assert args == kwargs
def _aggregations(search, definitions, urlkwargs, filters):
    """Add aggregations to query."""

    def without(d, keys):
        """Remove keys from dict."""
        new_d = d.copy()
        for key in keys:
            if key in new_d:
                new_d.pop(key)
        return new_d

    def get_facets_names(name, aggs):
        """Get facet names with the nested ones (only prefixed with facet_)."""
        if name.startswith('facet_'):
            names = [name.replace('facet_', '')]
        else:
            names = []

        if 'aggs' in aggs[name]:
            aggs = aggs[name]['aggs']
            for key in aggs.keys():
                if key.startswith('facet_'):
                    names.extend(get_facets_names(key, aggs))
                             
        return names

    if definitions:
        for name, agg in definitions.items():

            # get nested aggs names
            facets = get_facets_names(name, definitions)

            # collect filters except for aggs or nested aggs ones
            _filters, _ = _create_filter_dsl(urlkwargs,
                                             without(filters, facets))
            if _filters:
                agg = {
                    'filter': {
                        'bool': {
                            'must': [x.to_dict() for x in _filters]
                        }
                    },
                    'aggs': {
                        'filtered': agg
                    }
                }
            search.aggs[name] = agg
    return search
def _aggregations(search, definitions, urlkwargs, filters):
    """Add aggregations to query."""
    def without(d, keys):
        """Remove keys from dict."""
        new_d = d.copy()
        for key in keys:
            if key in new_d:
                new_d.pop(key)
        return new_d

    def get_facets_names(name, aggs):
        """Get facet names with the nested ones (only prefixed with facet_)."""
        if name.startswith('facet_'):
            names = [name.replace('facet_', '')]
        else:
            names = []

        if 'aggs' in aggs[name]:
            aggs = aggs[name]['aggs']
            for key in aggs.keys():
                if key.startswith('facet_'):
                    names.extend(get_facets_names(key, aggs))

        return names

    if definitions:
        for name, agg in definitions.items():

            # get nested aggs names
            facets = get_facets_names(name, definitions)

            # collect filters except for aggs or nested aggs ones
            _filters, _ = _create_filter_dsl(urlkwargs,
                                             without(filters, facets))
            if _filters:
                agg = {
                    'filter': {
                        'bool': {
                            'must': [x.to_dict() for x in _filters]
                        }
                    },
                    'aggs': {
                        'filtered': agg
                    }
                }
            search.aggs[name] = agg
    return search