def _get_field_search_query(field_parameters): """ Parameters ---------- field_parameters : list of query.search.field_search_parameter.FieldSearchParameter Returns ------- Q """ if not field_parameters: return Q() queries = [] for parameter in field_parameters: if not parameter.is_valid(): continue if not parameter.operator.fieldset_operator: continue query = AlertSearchResults._create_field_query(parameter) queries.append(query) return join_query(queries, 'AND') if queries else Q()
def _get_keyword_list_search_query(keywords, distilleries): """Create a search query that searches alerts for keywords. Parameters ---------- keywords : list of str Keywords to search for. distilleries: list of distilleries.models.Distillery Returns ------- Q """ if not keywords: return Q() text_fields = AlertSearchResults._get_shared_text_fields(distilleries) queries = [ AlertSearchResults._get_keyword_search_query(keyword, text_fields) for keyword in keywords ] if len(queries) == 1: return queries[0] return join_query(queries, 'AND')
def _get_alert_data_query(distillery, keywords): """Return a Q object that searches an alert's JSON data for keywords. Parameters ---------- distillery : Distillery Distillery that created an alert. keywords : list of str Keywords to search for in the alert data. Returns ------- Q """ text_fields = distillery.get_text_fields() field_names = [field.field_name for field in text_fields] field_keys = [name.replace('.', '__') for name in field_names] queries = [] for key in field_keys: query_field = 'data__{}__icontains'.format(key) keyword_queries = [ Q(**{query_field: keyword}) for keyword in keywords ] queries.extend(keyword_queries) field_query = join_query(queries, 'OR') return Q(distillery=distillery) & field_query
def _create_data_query(user, keywords): """Create a search query that searches the alert data for keywords. Parameters ---------- user : appusers.models.AppUser User making the search request. keywords : list of str Keywords to search for. Returns ------- Q """ distilleries = AlertSearchResults._get_distilleries_with_alerts(user) if distilleries: data_queries = [ AlertSearchResults._get_alert_data_query(distillery, keywords) for distillery in distilleries ] return join_query(data_queries, 'OR') return Q()
def _filter_by_value(self, queryset, value): """ """ distilleries = Distillery.objects.filter(alerts__in=queryset).distinct() if distilleries: queries = [self._get_data_query(distillery, value) \ for distillery in distilleries] data_query = join_query(queries, 'OR') title_query = self._get_title_query(value) return queryset.filter(title_query | data_query) else: return queryset.none()
def _get_data_query(distillery, value): """ """ text_fields = distillery.get_text_fields() field_names = [field.field_name for field in text_fields] field_keys = [name.replace('.', '__') for name in field_names] queries = [] for key in field_keys: query_exp = 'data__%s' % key kwarg = {query_exp: value} queries.append(Q(**kwarg)) field_query = join_query(queries, 'OR') return Q(distillery=distillery) & field_query
def _get_alert_search_queryset(query, after=None, before=None): """Return the queryset of alerts matching particular keywords. Parameters ---------- query : query.search.search_query.SearchQuery Keywords to search for. after: datetime before: datetime Returns ------- django.db.models.query.QuerySet """ alert_qs = Alert.objects.filter_by_user(query.user) distillery_qs = None if not query.user.is_staff: distillery_qs = Distillery.objects.filter( company=query.user.company) if query.distilleries.count(): distillery_qs = query.distilleries if distillery_qs: alert_qs = alert_qs.filter(distillery__in=distillery_qs) else: distillery_qs = Distillery.objects.all() if after: alert_qs = alert_qs.filter(created_date__gte=after) if before: alert_qs = alert_qs.filter(created_date__lte=before) keyword_query = AlertSearchResults._get_keyword_list_search_query( query.keywords, distillery_qs) field_query = AlertSearchResults._get_field_search_query( query.field_parameters) alert_qs = alert_qs.filter( join_query([keyword_query, field_query], 'AND')) return alert_qs
def _get_alert_search_query(user, keywords): """Create a search query that searches alerts for keywords. Parameters ---------- user : appuser.models.AppUser User requesting the search query. keywords : list of str Keywords to search for. Returns ------- Q """ queries = [] queries += [AlertSearchResults._create_data_query(user, keywords)] queries += AlertSearchResults._create_title_queries(keywords) queries += AlertSearchResults._create_note_queries(keywords) queries += AlertSearchResults._get_alert_comments_query(keywords) return join_query(queries, 'OR')
def _get_keyword_search_query(keyword, text_fields): """ Create a search query for searching by keyword. Parameters ---------- keyword : string text_fields : list of DataField Returns ------- Q """ queries = [ Q(title__icontains=keyword), Q(analysis__notes__icontains=keyword), Q(comments__content__icontains=keyword) ] for field in text_fields: underscored_field = field.replace('.', '__') query_field = 'data__{}__icontains'.format(underscored_field) queries.append(Q(**{query_field: keyword})) return join_query(queries, 'OR')