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)
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