Ejemplo n.º 1
0
    def get_navigation_story_count(self, navigations, section, company, user):
        """Get story count by navigation"""

        search = SearchQuery()
        self.prefill_search_args(search)
        self.prefill_search_items(search)
        search.section = section
        search.user = user
        search.company = company
        self.apply_section_filter(search)

        aggs = {'navigations': {'filters': {'filters': {}}}}

        for navigation in navigations:
            navigation_id = navigation.get('_id')
            products = get_products_by_navigation(navigation_id) or []
            navigation_filter = {
                'bool': {
                    'should': [],
                    'minimum_should_match': 1
                }
            }
            for product in products:
                if product.get('query'):
                    navigation_filter['bool']['should'].append(
                        query_string(product.get('query')))

            if navigation_filter['bool']['should']:
                aggs['navigations']['filters']['filters'][str(
                    navigation_id)] = navigation_filter

        source = {'query': search.query, 'aggs': aggs, 'size': 0}
        req = ParsedRequest()
        req.args = {'source': json.dumps(source)}

        try:
            results = self.internal_get(req, None)
            buckets = results.hits['aggregations']['navigations']['buckets']
            for navigation in navigations:
                navigation_id = navigation.get('_id')
                doc_count = buckets.get(str(navigation_id),
                                        {}).get('doc_count', 0)
                if doc_count > 0:
                    navigation['story_count'] = doc_count

        except Exception as exc:
            logger.error(
                'Error in get_navigation_story_count for query: {}'.format(
                    json.dumps(source)),
                exc,
                exc_info=True)
Ejemplo n.º 2
0
    def get_matching_topics(self, item_id, topics, users, companies):
        """ Returns a list of topic ids matching to the given item_id

        :param item_id: item id to be tested against all topics
        :param topics: list of topics
        :param users: user_id, user dictionary
        :param companies: company_id, company dictionary
        :return:
        """

        query = {
            'bool': {
                'must_not': [
                    {
                        'term': {
                            'type': 'composite'
                        }
                    },
                    {
                        'constant_score': {
                            'filter': {
                                'exists': {
                                    'field': 'nextversion'
                                }
                            }
                        }
                    },
                ],
                'must': [{
                    'term': {
                        '_id': item_id
                    }
                }],
                'should': []
            }
        }
        aggs = {'topics': {'filters': {'filters': {}}}}

        queried_topics = []
        # get all section filters
        section_filters = get_resource_service(
            'section_filters').get_section_filters_dict()

        for topic in topics:
            search = SearchQuery()

            user = users.get(str(topic['user']))
            if not user:
                continue

            search.user = user
            search.is_admin = is_admin(user)
            search.company = companies.get(str(user.get('company', '')))

            search.query = deepcopy(query)
            search.query['bool']['must'] = [{'term': {'_id': item_id}}]
            search.section = topic.get('topic_type')

            self.prefill_search_products(search)

            topic_filter = {'bool': {'must': []}}

            if topic.get('query'):
                topic_filter['bool']['must'].append(
                    query_string(topic['query']))

            if topic.get('created'):
                topic_filter['bool']['must'].append(
                    self.versioncreated_range(
                        dict(created_from=topic['created'].get('from'),
                             created_to=topic['created'].get('to'),
                             timezone_offset=topic.get('timezone_offset',
                                                       '0'))))

            if topic.get('filter'):
                topic_filter['bool']['must'] += self._filter_terms(
                    topic['filter'])

            # for now even if there's no active company matching for the user
            # continuing with the search
            try:
                self.validate_request(search)
                self.apply_section_filter(search, section_filters)
                self.apply_company_filter(search)
                self.apply_time_limit_filter(search)
                self.apply_products_filter(search)
            except Forbidden:
                logger.info(
                    'Notification for user:{} and topic:{} is skipped'.format(
                        user.get('_id'), topic.get('_id')))
                continue

            aggs['topics']['filters']['filters'][str(
                topic['_id'])] = topic_filter
            queried_topics.append(topic)

        source = {'query': query}
        source['aggs'] = aggs
        source['size'] = 0

        req = ParsedRequest()
        req.args = {'source': json.dumps(source)}
        topic_matches = []

        try:
            search_results = self.internal_get(req, None)

            for topic in queried_topics:
                if search_results.hits['aggregations']['topics']['buckets'][
                        str(topic['_id'])]['doc_count'] > 0:
                    topic_matches.append(topic['_id'])

        except Exception as exc:
            logger.error('Error in get_matching_topics for query: {}'.format(
                json.dumps(source)),
                         exc,
                         exc_info=True)

        return topic_matches