Esempio n. 1
0
    def _get_facet_terms(self, fields, request_context,
                         all_projects, limit_terms,
                         exclude_options=False):
        # Fields can be empty if there are no facet terms desired,
        # but we will run a size=0 search to get the doc count. If the
        # user does not want the options associated with the facet fields,
        # do not aggregate. This is controlled with a parameter to the
        # API call.
        body = {}
        term_aggregations = {}

        if fields:
            mapping = self.get_mapping()['properties']
            # Nested fields will be all the mapped fields with type=='nested'
            # Not tremendously keen on the way this is structured but the
            # nested fields are a bit special case
            nested_fields = [name
                             for name, properties in six.iteritems(mapping)
                             if properties['type'] == 'nested']
            if not exclude_options:
                term_aggregations = utils.get_facets_query(fields,
                                                           nested_fields,
                                                           limit_terms)
            if term_aggregations:
                body['aggs'] = term_aggregations

        role_filter = request_context.user_role_filter
        plugin_filters = [{
            "term": {ROLE_USER_FIELD: role_filter}
        }]
        if not (request_context.is_admin and all_projects):
            plugin_filters.extend(
                self._get_rbac_field_filters(request_context))

        body['query'] = {
            "filtered": {
                "filter": {
                    "and": plugin_filters
                }}}

        results = self.engine.search(
            index=self.alias_name_search,
            doc_type=self.get_document_type(),
            body=body,
            ignore_unavailable=True,
            size=0)

        agg_results = results.get('aggregations', {})
        doc_count = results['hits']['total']

        facet_terms = utils.transform_facets_results(
            agg_results,
            self.get_document_type())

        if term_aggregations and not agg_results:
            LOG.warning(_LW(
                "No aggregations found for %(resource_type)s. There may "
                "be a mapping problem.") %
                {'resource_type': self.get_document_type()})
        return facet_terms, doc_count
    def test_facet_result_transform(self):
        agg_results = {
            "simple": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [{"key": "VALUE1", "doc_count": 1}]
            },
            "nested.single": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "nested.single": {
                    "buckets": [{
                        "key": "SINGLE_VALUE1",
                        "doc_count": 1,
                        "nested.single__unique_docs": {
                            "doc_count": 1
                        }
                    }]
                }
            },
            "nested.list": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "nested.list": {
                    "doc_count_error_upper_bound": 0,
                    "sum_other_doc_count": 0,
                    "buckets": [{
                        "key": "LIST_VALUE1",
                        "doc_count": 2,
                        "nested.list__unique_docs": {
                            "doc_count": 1
                        }
                    }]
                }
            }
        }

        formatted = plugin_utils.transform_facets_results(
            agg_results,
            resource_type="fake")

        expected = {
            "simple": [
                {"key": "VALUE1", "doc_count": 1}
            ],
            "nested.single": [
                {"key": "SINGLE_VALUE1", "doc_count": 1}
            ],
            "nested.list": [
                {"key": "LIST_VALUE1", "doc_count": 1}
            ]
        }

        self.assertEqual(expected, formatted)
Esempio n. 3
0
    def test_facet_result_transform(self):
        agg_results = {
            "simple": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [{"key": "VALUE1", "doc_count": 1}]
            },
            "nested.single": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "nested.single": {
                    "buckets": [{
                        "key": "SINGLE_VALUE1",
                        "doc_count": 1,
                        "nested.single__unique_docs": {
                            "doc_count": 1
                        }
                    }]
                }
            },
            "nested.list": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "nested.list": {
                    "doc_count_error_upper_bound": 0,
                    "sum_other_doc_count": 0,
                    "buckets": [{
                        "key": "LIST_VALUE1",
                        "doc_count": 2,
                        "nested.list__unique_docs": {
                            "doc_count": 1
                        }
                    }]
                }
            }
        }

        formatted = plugin_utils.transform_facets_results(
            agg_results,
            resource_type="fake")

        expected = {
            "simple": [
                {"key": "VALUE1", "doc_count": 1}
            ],
            "nested.single": [
                {"key": "SINGLE_VALUE1", "doc_count": 1}
            ],
            "nested.list": [
                {"key": "LIST_VALUE1", "doc_count": 1}
            ]
        }

        self.assertEqual(expected, formatted)
Esempio n. 4
0
    def _get_facet_terms(self, fields, request_context,
                         all_projects, limit_terms):
        term_aggregations = utils.get_facets_query(fields, limit_terms)

        if term_aggregations:
            body = {
                'aggs': term_aggregations,
            }

            role_filter = request_context.user_role_filter
            plugin_filters = [{
                "term": {ROLE_USER_FIELD: role_filter}
            }]
            if not (request_context.is_admin and all_projects):
                plugin_filters.extend(
                    self._get_rbac_field_filters(request_context))

            body['query'] = {
                "filtered": {
                    "filter": {
                        "and": plugin_filters
                    }}}

            results = self.engine.search(
                index=self.alias_name_search,
                doc_type=self.get_document_type(),
                body=body,
                ignore_unavailable=True,
                size=0)

            agg_results = results.get('aggregations', {})
            facet_terms = utils.transform_facets_results(
                agg_results,
                self.get_document_type())

            if not agg_results:
                LOG.warning(_LW(
                    "No aggregations found for %(resource_type)s. There may "
                    "be a mapping problem.") %
                    {'resource_type': self.get_document_type()})
            return facet_terms
        return {}
Esempio n. 5
0
    def _get_facet_terms(self, fields, request_context,
                         all_projects, limit_terms,
                         exclude_options=False):
        # Fields can be empty if there are no facet terms desired,
        # but we will run a size=0 search to get the doc count. If the
        # user does not want the options associated with the facet fields,
        # do not aggregate. This is controlled with a parameter to the
        # API call.
        body = {}
        term_aggregations = {}

        if fields:
            mapping = self.get_mapping()['properties']
            # Nested fields will be all the mapped fields with type=='nested'
            # Not tremendously keen on the way this is structured but the
            # nested fields are a bit special case
            nested_fields = [name
                             for name, properties in mapping.items()
                             if properties['type'] == 'nested']
            if not exclude_options:
                term_aggregations = utils.get_facets_query(fields,
                                                           nested_fields,
                                                           limit_terms)
            if term_aggregations:
                body['aggs'] = term_aggregations

        role_filter = request_context.user_role_filter

        filter_query = {
            "bool": {
                "filter": {
                    "bool": {
                        "must": {
                            "term": {ROLE_USER_FIELD: role_filter}
                        }
                    }
                }
            }
        }

        # Add in the RBAC filters unless all_projects is requested
        if not (request_context.is_admin and all_projects):
            rbac_filters = self._get_rbac_field_filters(request_context)

            # minimum_should_match:1 is assumed in filter context,
            # but I'm including it explicitly so nobody spends an hour
            # scouring the documentation to check that is the case
            if rbac_filters:
                filter_query["bool"]["filter"]["bool"].update(
                    {"should": self._get_rbac_field_filters(request_context),
                     "minimum_should_match": 1})

        body['query'] = filter_query

        results = self.engine.search(
            index=self.alias_name_search,
            doc_type=self.get_document_type(),
            body=body,
            ignore_unavailable=True,
            size=0)

        agg_results = results.get('aggregations', {})
        doc_count = results['hits']['total']

        facet_terms = utils.transform_facets_results(
            agg_results,
            self.get_document_type())

        if term_aggregations and not agg_results:
            LOG.warning(
                "No aggregations found for %(resource_type)s. There may "
                "be a mapping problem." %
                {'resource_type': self.get_document_type()})
        return facet_terms, doc_count
Esempio n. 6
0
    def _get_facet_terms(self,
                         fields,
                         request_context,
                         all_projects,
                         limit_terms,
                         exclude_options=False):
        # Fields can be empty if there are no facet terms desired,
        # but we will run a size=0 search to get the doc count. If the
        # user does not want the options associated with the facet fields,
        # do not aggregate. This is controlled with a parameter to the
        # API call.
        body = {}
        term_aggregations = {}

        if fields:
            mapping = self.get_mapping()['properties']
            # Nested fields will be all the mapped fields with type=='nested'
            # Not tremendously keen on the way this is structured but the
            # nested fields are a bit special case
            nested_fields = [
                name for name, properties in mapping.items()
                if properties['type'] == 'nested'
            ]
            if not exclude_options:
                term_aggregations = utils.get_facets_query(
                    fields, nested_fields, limit_terms)
            if term_aggregations:
                body['aggs'] = term_aggregations

        role_filter = request_context.user_role_filter

        filter_query = {
            "bool": {
                "filter": {
                    "bool": {
                        "must": {
                            "term": {
                                ROLE_USER_FIELD: role_filter
                            }
                        }
                    }
                }
            }
        }

        # Add in the RBAC filters unless all_projects is requested
        if not (request_context.is_admin and all_projects):
            rbac_filters = self._get_rbac_field_filters(request_context)

            # minimum_should_match:1 is assumed in filter context,
            # but I'm including it explicitly so nobody spends an hour
            # scouring the documentation to check that is the case
            if rbac_filters:
                filter_query["bool"]["filter"]["bool"].update({
                    "should":
                    self._get_rbac_field_filters(request_context),
                    "minimum_should_match":
                    1
                })

        body['query'] = filter_query

        results = self.engine.search(index=self.alias_name_search,
                                     doc_type=self.get_document_type(),
                                     body=body,
                                     ignore_unavailable=True,
                                     size=0)

        agg_results = results.get('aggregations', {})
        doc_count = results['hits']['total']

        facet_terms = utils.transform_facets_results(agg_results,
                                                     self.get_document_type())

        if term_aggregations and not agg_results:
            LOG.warning(
                "No aggregations found for %(resource_type)s. There may "
                "be a mapping problem." %
                {'resource_type': self.get_document_type()})
        return facet_terms, doc_count