Exemplo n.º 1
0
def contact_es_search(org, text, base_group=None, sort_struct=None):
    """
    Returns ES query
    """

    if not base_group:
        base_group = org.cached_all_contacts_group

    if not sort_struct:
        sort_field = "-id"
    else:
        if sort_struct["field_type"] == "field":
            sort_field = {
                sort_struct["field_path"]: {
                    "order": sort_struct["sort_direction"],
                    "nested": {
                        "path": "fields",
                        "filter": {
                            "term": {
                                "fields.field": sort_struct["field_uuid"]
                            }
                        }
                    },
                }
            }
        else:
            sort_field = {
                sort_struct["field_name"]: {
                    "order": sort_struct["sort_direction"]
                }
            }

    es_filter = es_Q(
        "bool",
        filter=[
            # es_Q('term', is_blocked=False),
            # es_Q('term', is_stopped=False),
            es_Q("term", org_id=org.id),
            es_Q("term", groups=str(base_group.uuid)),
        ],
    )

    if text:
        parsed = parse_query(text, as_anon=org.is_anon)
        es_match = parsed.as_elasticsearch(org)
    else:
        parsed = None
        es_match = es_Q()

    return (
        (ModelESSearch(model=Contact, index="contacts").params(
            routing=org.id).query(es_match & es_filter).sort(sort_field)),
        parsed,
    )
Exemplo n.º 2
0
def contact_es_search(org, text, base_group=None, sort_struct=None):
    """
    Returns ES query
    """

    if not base_group:
        base_group = org.cached_all_contacts_group

    if not sort_struct:
        sort_field = "-id"
    else:
        if sort_struct["field_type"] == "field":
            sort_field = {
                sort_struct["field_path"]: {
                    "order": sort_struct["sort_direction"],
                    "nested": {"path": "fields", "filter": {"term": {"fields.field": sort_struct["field_uuid"]}}},
                }
            }
        else:
            sort_field = {sort_struct["field_name"]: {"order": sort_struct["sort_direction"]}}

    es_filter = es_Q(
        "bool",
        filter=[
            # es_Q('term', is_blocked=False),
            # es_Q('term', is_stopped=False),
            es_Q("term", org_id=org.id),
            es_Q("term", groups=str(base_group.uuid)),
        ],
    )

    if text:
        parsed = parse_query(text, as_anon=org.is_anon)
        es_match = parsed.as_elasticsearch(org)
    else:
        parsed = None
        es_match = es_Q()

    return (
        (
            ModelESSearch(model=Contact, index="contacts")
            .params(routing=org.id)
            .query(es_match & es_filter)
            .sort(sort_field)
        ),
        parsed,
    )
Exemplo n.º 3
0
def contact_es_search(org, text, base_group=None):
    """
    Returns ES query
    """

    if not base_group:
        base_group = org.cached_all_contacts_group

    es_filter = es_Q(
        'bool',
        filter=[
            # es_Q('term', is_blocked=False),
            # es_Q('term', is_stopped=False),
            es_Q('term', org_id=org.id),
            es_Q('term', groups=six.text_type(base_group.uuid))
        ])

    parsed = parse_query(text, as_anon=org.is_anon)
    es_match = parsed.as_elasticsearch(org)

    return (ModelESSearch(model=Contact, index='contacts').params(
        routing=org.id).query(es_match
                              & es_filter).sort('-modified_on_mu')), parsed
Exemplo n.º 4
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if self.comparator.lower() in self.IS_SET_LOOKUPS:
            is_set = True
        elif self.comparator.lower() in self.IS_NOT_SET_LOOKUPS:
            is_set = False
        else:
            raise SearchException(_("Invalid operator for empty string comparison"))

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = str(field.uuid)
            es_query = es_Q("term", **{"fields.field": field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                field_name = "fields.text"
            elif field.value_type == Value.TYPE_NUMBER:
                field_name = "fields.number"
            elif field.value_type == Value.TYPE_DATETIME:
                field_name = "fields.datetime"
            elif field.value_type == Value.TYPE_STATE:
                field_name = "fields.state"
            elif field.value_type == Value.TYPE_DISTRICT:
                field_name = "fields.district"
            elif field.value_type == Value.TYPE_WARD:
                field_name = "fields.ward"
            else:  # pragma: no cover
                raise SearchException(_(f"Unrecognized contact field type '{field.value_type}'"))

            es_query &= es_Q("exists", **{"field": field_name})

            if is_set:
                return es_Q("nested", path="fields", query=es_query)
            else:
                return ~es_Q("nested", path="fields", query=es_query)
        elif prop_type == ContactQuery.PROP_SCHEME:
            if org.is_anon:
                return es_Q("ids", **{"values": [-1]})

            es_query = es_Q("exists", **{"field": "urns.path"}) & es_Q("term", **{"urns.scheme": field.lower()})

            if is_set:
                return es_Q("nested", path="urns", query=es_query)
            else:
                return ~es_Q("nested", path="urns", query=es_query)
        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            field_key = field.key

            if field_key == "name":
                if is_set:
                    es_query = es_Q("exists", **{"field": "name"}) & ~es_Q("term", **{"name.keyword": ""})
                else:
                    es_query = ~(es_Q("exists", **{"field": "name"}) & ~es_Q("term", **{"name.keyword": ""}))
                return es_query
            elif field_key == "language":
                if is_set:
                    es_query = es_Q("exists", **{"field": "language"}) & ~es_Q("term", **{"language": ""})
                else:
                    es_query = ~(es_Q("exists", **{"field": "language"}) & ~es_Q("term", **{"language": ""}))
                return es_query
            elif field_key == "id":
                raise SearchException(_("All contacts have an 'id', it's not possible to check if 'id' is set"))
            elif field_key == "created_on":
                raise SearchException(
                    _("All contacts have a 'created_on', it's not possible to check if 'created_on' is set")
                )
            else:  # pragma: no cover
                raise SearchException(_(f"Unknown attribute field '{field}'"))
        else:  # pragma: no cover
            raise SearchException(_(f"Unrecognized contact field type '{prop_type}'"))
Exemplo n.º 5
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = str(field.uuid)
            es_query = es_Q("term", **{"fields.field": field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                query_value = self.value.lower()

                if self.comparator == "=":
                    es_query &= es_Q("term", **{"fields.text": query_value})
                elif self.comparator == "!=":
                    es_query &= es_Q("term", **{"fields.text": query_value})
                    es_query &= es_Q("exists", **{"field": "fields.text"})

                    # search for the inverse of what was specified
                    return ~es_Q("nested", path="fields", query=es_query)

                else:
                    raise SearchException(_(f"Unknown text comparator: '{self.comparator}'"))

            elif field.value_type == Value.TYPE_NUMBER:
                query_value = str(self._parse_number(self.value))

                if self.comparator == "=":
                    es_query &= es_Q("match", **{"fields.number": query_value})
                elif self.comparator == ">":
                    es_query &= es_Q("range", **{"fields.number": {"gt": query_value}})
                elif self.comparator == ">=":
                    es_query &= es_Q("range", **{"fields.number": {"gte": query_value}})
                elif self.comparator == "<":
                    es_query &= es_Q("range", **{"fields.number": {"lt": query_value}})
                elif self.comparator == "<=":
                    es_query &= es_Q("range", **{"fields.number": {"lte": query_value}})
                else:
                    raise SearchException(_(f"Unknown number comparator: '{self.comparator}'"))

            elif field.value_type == Value.TYPE_DATETIME:
                query_value = str_to_date(self.value, field.org.get_dayfirst())

                if not query_value:
                    raise SearchException(_(f"Unable to parse the date '{self.value}'"))

                # datetime contact values are serialized as ISO8601 timestamps in local time on ElasticSearch
                lower_bound, upper_bound = date_to_day_range_utc(query_value, org)

                if self.comparator == "=":
                    es_query &= es_Q(
                        "range", **{"fields.datetime": {"gte": lower_bound.isoformat(), "lt": upper_bound.isoformat()}}
                    )
                elif self.comparator == ">":
                    es_query &= es_Q("range", **{"fields.datetime": {"gte": upper_bound.isoformat()}})
                elif self.comparator == ">=":
                    es_query &= es_Q("range", **{"fields.datetime": {"gte": lower_bound.isoformat()}})
                elif self.comparator == "<":
                    es_query &= es_Q("range", **{"fields.datetime": {"lt": lower_bound.isoformat()}})
                elif self.comparator == "<=":
                    es_query &= es_Q("range", **{"fields.datetime": {"lt": upper_bound.isoformat()}})
                else:
                    raise SearchException(_(f"Unknown datetime comparator: '{self.comparator}'"))

            elif field.value_type in (Value.TYPE_STATE, Value.TYPE_DISTRICT, Value.TYPE_WARD):
                query_value = self.value.lower()

                if field.value_type == Value.TYPE_WARD:
                    field_name = "fields.ward"
                elif field.value_type == Value.TYPE_DISTRICT:
                    field_name = "fields.district"
                elif field.value_type == Value.TYPE_STATE:
                    field_name = "fields.state"
                else:  # pragma: no cover
                    raise SearchException(_(f"Unknown location type: '{field.value_type}'"))

                if self.comparator == "=":
                    field_name += "_keyword"
                    es_query &= es_Q("term", **{field_name: query_value})
                elif self.comparator == "!=":
                    field_name += "_keyword"
                    es_query &= es_Q("term", **{field_name: query_value})
                    es_query &= es_Q("exists", **{"field": field_name})

                    return ~es_Q("nested", path="fields", query=es_query)

                else:
                    raise SearchException(_(f"Unsupported comparator '{self.comparator}' for location field"))

            else:  # pragma: no cover
                raise SearchException(_(f"Unrecognized contact field type '{field.value_type}'"))

            return es_Q("nested", path="fields", query=es_query)

        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            query_value = self.value.lower()

            field_key = field.key

            if field_key == "name":
                if self.comparator == "=":
                    field_name = "name.keyword"
                    es_query = es_Q("term", **{field_name: query_value})
                elif self.comparator == "~":
                    field_name = "name"
                    es_query = es_Q("match", **{field_name: query_value})
                elif self.comparator == "!=":
                    field_name = "name.keyword"
                    es_query = ~es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(_(f"Unknown attribute comparator: '{self.comparator}'"))
            elif field_key == "id":
                es_query = es_Q("ids", **{"values": [query_value]})
            elif field_key == "language":
                if self.comparator == "=":
                    field_name = "language"
                    es_query = es_Q("term", **{field_name: query_value})
                elif self.comparator == "!=":
                    field_name = "language"
                    es_query = ~es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(_(f"Unknown attribute comparator: '{self.comparator}'"))
            elif field_key == "created_on":
                query_value = str_to_date(self.value, field.org.get_dayfirst())

                if not query_value:
                    raise SearchException(_(f"Unable to parse the date '{self.value}'"))

                # contact created_on is serialized as ISO8601 timestamp in utc time on ElasticSearch
                lower_bound, upper_bound = date_to_day_range_utc(query_value, org)

                if self.comparator == "=":
                    es_query = es_Q(
                        "range", **{"created_on": {"gte": lower_bound.isoformat(), "lt": upper_bound.isoformat()}}
                    )
                elif self.comparator == ">":
                    es_query = es_Q("range", **{"created_on": {"gte": upper_bound.isoformat()}})
                elif self.comparator == ">=":
                    es_query = es_Q("range", **{"created_on": {"gte": lower_bound.isoformat()}})
                elif self.comparator == "<":
                    es_query = es_Q("range", **{"created_on": {"lt": lower_bound.isoformat()}})
                elif self.comparator == "<=":
                    es_query = es_Q("range", **{"created_on": {"lt": upper_bound.isoformat()}})
                else:
                    raise SearchException(_(f"Unknown created_on comparator: '{self.comparator}'"))
            else:  # pragma: no cover
                raise SearchException(_(f"Unknown attribute field '{field}'"))
            return es_query

        elif prop_type == ContactQuery.PROP_SCHEME:
            query_value = self.value.lower()
            es_query = es_Q("term", **{"urns.scheme": field.lower()})

            if org.is_anon:
                return es_Q("ids", **{"values": [-1]})
            else:
                if self.comparator == "=":
                    es_query &= es_Q("term", **{"urns.path.keyword": query_value})
                elif self.comparator == "~":
                    es_query &= es_Q("match_phrase", **{"urns.path": query_value})
                else:
                    raise SearchException(_(f"Unknown scheme comparator: '{self.comparator}'"))

                return es_Q("nested", path="urns", query=es_query)
        else:  # pragma: no cover
            raise SearchException(_(f"Unrecognized contact field type '{prop_type}'"))
Exemplo n.º 6
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = str(field.uuid)
            es_query = es_Q("term", **{"fields.field": field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                query_value = self.value.lower()

                if self.comparator == "=":
                    es_query &= es_Q("term", **{"fields.text": query_value})

                else:
                    raise SearchException(
                        _(f"Unknown text comparator: '{self.comparator}'"))

            elif field.value_type == Value.TYPE_NUMBER:
                query_value = str(self._parse_number(self.value))

                if self.comparator == "=":
                    es_query &= es_Q("match", **{"fields.number": query_value})
                elif self.comparator == ">":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "gt": query_value
                                     }})
                elif self.comparator == ">=":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "gte": query_value
                                     }})
                elif self.comparator == "<":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "lt": query_value
                                     }})
                elif self.comparator == "<=":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "lte": query_value
                                     }})
                else:
                    raise SearchException(
                        _(f"Unknown number comparator: '{self.comparator}'"))

            elif field.value_type == Value.TYPE_DATETIME:
                utc_range = calculate_utc_range(org, self.value)

                if self.comparator == "=":
                    es_query &= es_Q(
                        "range",
                        **{
                            "fields.datetime": {
                                "gte": utc_range[0].isoformat(),
                                "lt": utc_range[1].isoformat()
                            }
                        },
                    )
                elif self.comparator == ">":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "gte": utc_range[1].isoformat()
                            }
                        })
                elif self.comparator == ">=":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "gte": utc_range[0].isoformat()
                            }
                        })
                elif self.comparator == "<":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "lt": utc_range[0].isoformat()
                            }
                        })
                elif self.comparator == "<=":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "lt": utc_range[1].isoformat()
                            }
                        })
                else:
                    raise SearchException(
                        _(f"Unknown datetime comparator: '{self.comparator}'"))

            elif field.value_type in (Value.TYPE_STATE, Value.TYPE_DISTRICT,
                                      Value.TYPE_WARD):
                query_value = self.value.lower()

                if field.value_type == Value.TYPE_WARD:
                    field_name = "fields.ward"
                elif field.value_type == Value.TYPE_DISTRICT:
                    field_name = "fields.district"
                elif field.value_type == Value.TYPE_STATE:
                    field_name = "fields.state"
                else:  # pragma: no cover
                    raise SearchException(
                        _(f"Unknown location type: '{field.value_type}'"))

                if self.comparator == "=":
                    field_name += "_keyword"
                    es_query &= es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(
                        _(f"Unsupported comparator '{self.comparator}' for location field"
                          ))

            else:  # pragma: no cover
                raise SearchException(
                    _(f"Unrecognized contact field type '{field.value_type}'"))

            return es_Q("nested", path="fields", query=es_query)

        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            query_value = self.value.lower()

            field_key = field.key

            if field_key == "name":
                if self.comparator == "=":
                    field_name = "name.keyword"
                    es_query = es_Q("term", **{field_name: query_value})
                elif self.comparator == "~":
                    field_name = "name"
                    es_query = es_Q("match", **{field_name: query_value})
                else:
                    raise SearchException(
                        _(f"Unknown attribute comparator: '{self.comparator}'")
                    )
            elif field_key == "id":
                es_query = es_Q("ids", **{"values": [query_value]})
            elif field_key == "language":
                if self.comparator == "=":
                    field_name = "language"
                    es_query = es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(
                        _(f"Unknown attribute comparator: '{self.comparator}'")
                    )
            elif field_key == "created_on":
                utc_range = calculate_utc_range(org, self.value)
                if self.comparator == "=":
                    es_query = es_Q(
                        "range", **{
                            "created_on": {
                                "gte": utc_range[0].isoformat(),
                                "lt": utc_range[1].isoformat()
                            }
                        })
                elif self.comparator == ">":
                    es_query = es_Q(
                        "range",
                        **{"created_on": {
                            "gte": utc_range[1].isoformat()
                        }})
                elif self.comparator == ">=":
                    es_query = es_Q(
                        "range",
                        **{"created_on": {
                            "gte": utc_range[0].isoformat()
                        }})
                elif self.comparator == "<":
                    es_query = es_Q(
                        "range",
                        **{"created_on": {
                            "lt": utc_range[0].isoformat()
                        }})
                elif self.comparator == "<=":
                    es_query = es_Q(
                        "range",
                        **{"created_on": {
                            "lt": utc_range[1].isoformat()
                        }})
                else:
                    raise SearchException(
                        _(f"Unknown created_on comparator: '{self.comparator}'"
                          ))
            else:  # pragma: no cover
                raise SearchException(_(f"Unknown attribute field '{field}'"))
            return es_query

        elif prop_type == ContactQuery.PROP_SCHEME:
            query_value = self.value.lower()
            es_query = es_Q("term", **{"urns.scheme": field.lower()})

            if org.is_anon:
                return es_Q("ids", **{"values": [-1]})
            else:
                if self.comparator == "=":
                    es_query &= es_Q("term",
                                     **{"urns.path.keyword": query_value})
                elif self.comparator == "~":
                    es_query &= es_Q("match_phrase",
                                     **{"urns.path": query_value})
                else:
                    raise SearchException(
                        _(f"Unknown scheme comparator: '{self.comparator}'"))

                return es_Q("nested", path="urns", query=es_query)
        else:  # pragma: no cover
            raise SearchException(
                _(f"Unrecognized contact field type '{prop_type}'"))
Exemplo n.º 7
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = str(field.uuid)
            es_query = es_Q("term", **{"fields.field": field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                query_value = self.value.lower()

                if self.comparator == "=":
                    es_query &= es_Q("term", **{"fields.text": query_value})

                else:
                    raise SearchException(
                        _("Unknown text comparator: '%s'") %
                        (self.comparator, ))

            elif field.value_type == Value.TYPE_NUMBER:
                query_value = str(self._parse_number(self.value))

                if self.comparator == "=":
                    es_query &= es_Q("match", **{"fields.number": query_value})
                elif self.comparator == ">":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "gt": query_value
                                     }})
                elif self.comparator == ">=":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "gte": query_value
                                     }})
                elif self.comparator == "<":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "lt": query_value
                                     }})
                elif self.comparator == "<=":
                    es_query &= es_Q("range",
                                     **{"fields.number": {
                                         "lte": query_value
                                     }})
                else:
                    raise SearchException(
                        _("Unknown number comparator: '%s'") %
                        (self.comparator, ))

            elif field.value_type == Value.TYPE_DATETIME:
                query_value = str_to_datetime(self.value,
                                              field.org.timezone,
                                              field.org.get_dayfirst(),
                                              fill_time=False)

                if not query_value:
                    raise SearchException(
                        _("Unable to parse the date '%s'") % self.value)

                utc_range = date_to_utc_range(query_value.date(), field.org)

                if self.comparator == "=":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "gte": utc_range[0].isoformat(),
                                "lt": utc_range[1].isoformat()
                            }
                        })
                elif self.comparator == ">":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "gte": utc_range[1].isoformat()
                            }
                        })
                elif self.comparator == ">=":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "gte": utc_range[0].isoformat()
                            }
                        })
                elif self.comparator == "<":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "lt": utc_range[0].isoformat()
                            }
                        })
                elif self.comparator == "<=":
                    es_query &= es_Q(
                        "range", **{
                            "fields.datetime": {
                                "lt": utc_range[1].isoformat()
                            }
                        })
                else:
                    raise SearchException(
                        _("Unknown datetime comparator: '%s'") %
                        (self.comparator, ))

            elif field.value_type in (Value.TYPE_STATE, Value.TYPE_DISTRICT,
                                      Value.TYPE_WARD):
                query_value = self.value.lower()

                if field.value_type == Value.TYPE_WARD:
                    field_name = "fields.ward"
                elif field.value_type == Value.TYPE_DISTRICT:
                    field_name = "fields.district"
                elif field.value_type == Value.TYPE_STATE:
                    field_name = "fields.state"
                else:  # pragma: no cover
                    raise SearchException(
                        _("Unknown location type: '%s'") %
                        (field.value_type, ))

                if self.comparator == "=":
                    field_name += "_keyword"
                    es_query &= es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(
                        _("Unsupported comparator '%s' for location field") %
                        self.comparator)

            else:  # pragma: no cover
                raise SearchException(
                    _("Unrecognized contact field type '%s'") %
                    field.value_type)

            return es_Q("nested", path="fields", query=es_query)

        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            query_value = self.value.lower()
            if field == "name":
                if self.comparator == "=":
                    field_name = "name.keyword"
                    es_query = es_Q("term", **{field_name: query_value})
                elif self.comparator == "~":
                    field_name = "name"
                    es_query = es_Q("match", **{field_name: query_value})
                else:
                    raise SearchException(
                        _("Unknown attribute comparator: '%s'") %
                        (self.comparator, ))
            elif field == "id":
                es_query = es_Q("ids", **{"values": [query_value]})
            else:  # pragma: no cover
                raise SearchException(
                    _("Unknown attribute field '%s'") % (field, ))
            return es_query

        elif prop_type == ContactQuery.PROP_SCHEME:
            query_value = self.value.lower()
            es_query = es_Q("term", **{"urns.scheme": field.lower()})

            if org.is_anon:
                return es_Q("ids", **{"values": [-1]})
            else:
                if self.comparator == "=":
                    es_query &= es_Q("term",
                                     **{"urns.path.keyword": query_value})
                elif self.comparator == "~":
                    es_query &= es_Q("match_phrase",
                                     **{"urns.path": query_value})
                else:
                    raise SearchException(
                        _("Unknown scheme comparator: '%s'") %
                        (self.comparator, ))

                return es_Q("nested", path="urns", query=es_query)
        else:  # pragma: no cover
            raise SearchException(
                _("Unrecognized contact field type '%s'") % prop_type)
Exemplo n.º 8
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if self.comparator.lower() in self.IS_SET_LOOKUPS:
            is_set = True
        elif self.comparator.lower() in self.IS_NOT_SET_LOOKUPS:
            is_set = False
        else:
            raise SearchException(
                _("Invalid operator for empty string comparison"))

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = six.text_type(field.uuid)
            es_query = es_Q('term', **{'fields.field': field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                field_name = 'fields.text'
            elif field.value_type == Value.TYPE_NUMBER:
                field_name = 'fields.number'
            elif field.value_type == Value.TYPE_DATETIME:
                field_name = 'fields.datetime'
            elif field.value_type == Value.TYPE_STATE:
                field_name = 'fields.state'
            elif field.value_type == Value.TYPE_DISTRICT:
                field_name = 'fields.district'
            elif field.value_type == Value.TYPE_WARD:
                field_name = 'fields.ward'
            else:  # pragma: no cover
                raise SearchException(
                    _("Unrecognized contact field type '%s'") %
                    (field.value_type, ))

            es_query &= es_Q('exists', **{'field': field_name})

            if is_set:
                return es_Q('nested', path='fields', query=es_query)
            else:
                return ~es_Q('nested', path='fields', query=es_query)
        elif prop_type == ContactQuery.PROP_SCHEME:
            if org.is_anon:
                return es_Q('ids', **{'values': [-1]})

            es_query = es_Q('exists', **{'field': 'urns.path'}) & es_Q(
                'term', **{'urns.scheme': field.lower()})

            if is_set:
                return es_Q('nested', path='urns', query=es_query)
            else:
                return ~es_Q('nested', path='urns', query=es_query)
        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            if field == 'name':
                if is_set:
                    es_query = es_Q('exists', **{
                        'field': 'name'
                    }) & ~es_Q('term', **{'name.keyword': ''})
                else:
                    es_query = ~(es_Q('exists', **{'field': 'name'})
                                 & ~es_Q('term', **{'name.keyword': ''}))
                return es_query
            elif field == 'id':
                raise SearchException(
                    "All contacts have an ID, you cannot check if 'id' is set")
            else:  # pragma: no cover
                raise SearchException(
                    _("Unknown attribute field '%s'") % (field, ))
        else:  # pragma: no cover
            raise SearchException(
                _("Unrecognized contact field type '%s'") % (prop_type, ))
Exemplo n.º 9
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = six.text_type(field.uuid)
            es_query = es_Q('term', **{'fields.field': field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                query_value = self.value.lower()

                if self.comparator == '=':
                    es_query &= es_Q('term', **{'fields.text': query_value})

                else:
                    raise SearchException(
                        _("Unknown text comparator: '%s'") %
                        (self.comparator, ))

            elif field.value_type == Value.TYPE_NUMBER:
                query_value = six.text_type(self._parse_number(self.value))

                if self.comparator == '=':
                    es_query &= es_Q('match', **{'fields.number': query_value})
                elif self.comparator == '>':
                    es_query &= es_Q('range',
                                     **{'fields.number': {
                                         'gt': query_value
                                     }})
                elif self.comparator == '>=':
                    es_query &= es_Q('range',
                                     **{'fields.number': {
                                         'gte': query_value
                                     }})
                elif self.comparator == '<':
                    es_query &= es_Q('range',
                                     **{'fields.number': {
                                         'lt': query_value
                                     }})
                elif self.comparator == '<=':
                    es_query &= es_Q('range',
                                     **{'fields.number': {
                                         'lte': query_value
                                     }})
                else:
                    raise SearchException(
                        _("Unknown number comparator: '%s'") %
                        (self.comparator, ))

            elif field.value_type == Value.TYPE_DATETIME:
                query_value = str_to_datetime(self.value,
                                              field.org.timezone,
                                              field.org.get_dayfirst(),
                                              fill_time=False)

                if not query_value:
                    raise SearchException(
                        _("Unable to parse the date '%s'") % self.value)

                utc_range = date_to_utc_range(query_value.date(), field.org)

                if self.comparator == '=':
                    es_query &= es_Q(
                        'range', **{
                            'fields.datetime': {
                                'gte': utc_range[0].isoformat(),
                                'lt': utc_range[1].isoformat()
                            }
                        })
                elif self.comparator == '>':
                    es_query &= es_Q(
                        'range', **{
                            'fields.datetime': {
                                'gte': utc_range[1].isoformat()
                            }
                        })
                elif self.comparator == '>=':
                    es_query &= es_Q(
                        'range', **{
                            'fields.datetime': {
                                'gte': utc_range[0].isoformat()
                            }
                        })
                elif self.comparator == '<':
                    es_query &= es_Q(
                        'range', **{
                            'fields.datetime': {
                                'lt': utc_range[0].isoformat()
                            }
                        })
                elif self.comparator == '<=':
                    es_query &= es_Q(
                        'range', **{
                            'fields.datetime': {
                                'lt': utc_range[1].isoformat()
                            }
                        })
                else:
                    raise SearchException(
                        _("Unknown datetime comparator: '%s'") %
                        (self.comparator, ))

            elif field.value_type in (Value.TYPE_STATE, Value.TYPE_DISTRICT,
                                      Value.TYPE_WARD):
                query_value = self.value.lower()

                if field.value_type == Value.TYPE_WARD:
                    field_name = 'fields.ward'
                elif field.value_type == Value.TYPE_DISTRICT:
                    field_name = 'fields.district'
                elif field.value_type == Value.TYPE_STATE:
                    field_name = 'fields.state'
                else:  # pragma: no cover
                    raise SearchException(
                        _("Unknown location type: '%s'") %
                        (field.value_type, ))

                if self.comparator == '=':
                    field_name += '.keyword'
                    es_query &= es_Q('term', **{field_name: query_value})
                else:
                    raise SearchException(
                        _("Unsupported comparator '%s' for location field") %
                        self.comparator)

            else:  # pragma: no cover
                raise SearchException(
                    _("Unrecognized contact field type '%s'") %
                    field.value_type)

            return es_Q('nested', path='fields', query=es_query)

        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            query_value = self.value.lower()
            if field == 'name':
                if self.comparator == '=':
                    field_name = 'name.keyword'
                    es_query = es_Q('term', **{field_name: query_value})
                elif self.comparator == '~':
                    field_name = 'name'
                    es_query = es_Q('match', **{field_name: query_value})
                else:
                    raise SearchException(
                        _("Unknown attribute comparator: '%s'") %
                        (self.comparator, ))
            elif field == 'id':
                es_query = es_Q('ids', **{'values': [query_value]})
            else:  # pragma: no cover
                raise SearchException(
                    _("Unknown attribute field '%s'") % (field, ))
            return es_query

        elif prop_type == ContactQuery.PROP_SCHEME:
            query_value = self.value.lower()
            es_query = es_Q('term', **{'urns.scheme': field.lower()})

            if org.is_anon:
                return es_Q('ids', **{'values': [-1]})
            else:
                if self.comparator == '=':
                    es_query &= es_Q('term',
                                     **{'urns.path.keyword': query_value})
                elif self.comparator == '~':
                    es_query &= es_Q('match_phrase',
                                     **{'urns.path': query_value})
                else:
                    raise SearchException(
                        _("Unknown scheme comparator: '%s'") %
                        (self.comparator, ))

                return es_Q('nested', path='urns', query=es_query)
        else:  # pragma: no cover
            raise SearchException(
                _("Unrecognized contact field type '%s'") % prop_type)
Exemplo n.º 10
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if self.comparator.lower() in self.IS_SET_LOOKUPS:
            is_set = True
        elif self.comparator.lower() in self.IS_NOT_SET_LOOKUPS:
            is_set = False
        else:
            raise SearchException(_("Invalid operator for empty string comparison"))

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = str(field.uuid)
            es_query = es_Q("term", **{"fields.field": field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                field_name = "fields.text"
            elif field.value_type == Value.TYPE_NUMBER:
                field_name = "fields.number"
            elif field.value_type == Value.TYPE_DATETIME:
                field_name = "fields.datetime"
            elif field.value_type == Value.TYPE_STATE:
                field_name = "fields.state"
            elif field.value_type == Value.TYPE_DISTRICT:
                field_name = "fields.district"
            elif field.value_type == Value.TYPE_WARD:
                field_name = "fields.ward"
            else:  # pragma: no cover
                raise SearchException(_(f"Unrecognized contact field type '{field.value_type}'"))

            es_query &= es_Q("exists", **{"field": field_name})

            if is_set:
                return es_Q("nested", path="fields", query=es_query)
            else:
                return ~es_Q("nested", path="fields", query=es_query)
        elif prop_type == ContactQuery.PROP_SCHEME:
            if org.is_anon:
                return es_Q("ids", **{"values": [-1]})

            es_query = es_Q("exists", **{"field": "urns.path"}) & es_Q("term", **{"urns.scheme": field.lower()})

            if is_set:
                return es_Q("nested", path="urns", query=es_query)
            else:
                return ~es_Q("nested", path="urns", query=es_query)
        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            field_key = field.key

            if field_key == "name":
                if is_set:
                    es_query = es_Q("exists", **{"field": "name"}) & ~es_Q("term", **{"name.keyword": ""})
                else:
                    es_query = ~(es_Q("exists", **{"field": "name"}) & ~es_Q("term", **{"name.keyword": ""}))
                return es_query
            elif field_key == "language":
                if is_set:
                    es_query = es_Q("exists", **{"field": "language"}) & ~es_Q("term", **{"language": ""})
                else:
                    es_query = ~(es_Q("exists", **{"field": "language"}) & ~es_Q("term", **{"language": ""}))
                return es_query
            elif field_key == "id":
                raise SearchException(_("All contacts have an 'id', it's not possible to check if 'id' is set"))
            elif field_key == "created_on":
                raise SearchException(
                    _("All contacts have a 'created_on', it's not possible to check if 'created_on' is set")
                )
            else:  # pragma: no cover
                raise SearchException(_(f"Unknown attribute field '{field}'"))
        else:  # pragma: no cover
            raise SearchException(_(f"Unrecognized contact field type '{prop_type}'"))
Exemplo n.º 11
0
    def as_elasticsearch(self, org, prop_map):
        prop_type, field = prop_map[self.prop]

        if prop_type == ContactQuery.PROP_FIELD:
            field_uuid = str(field.uuid)
            es_query = es_Q("term", **{"fields.field": field_uuid})

            if field.value_type == Value.TYPE_TEXT:
                query_value = self.value.lower()

                if self.comparator == "=":
                    es_query &= es_Q("term", **{"fields.text": query_value})

                else:
                    raise SearchException(_(f"Unknown text comparator: '{self.comparator}'"))

            elif field.value_type == Value.TYPE_NUMBER:
                query_value = str(self._parse_number(self.value))

                if self.comparator == "=":
                    es_query &= es_Q("match", **{"fields.number": query_value})
                elif self.comparator == ">":
                    es_query &= es_Q("range", **{"fields.number": {"gt": query_value}})
                elif self.comparator == ">=":
                    es_query &= es_Q("range", **{"fields.number": {"gte": query_value}})
                elif self.comparator == "<":
                    es_query &= es_Q("range", **{"fields.number": {"lt": query_value}})
                elif self.comparator == "<=":
                    es_query &= es_Q("range", **{"fields.number": {"lte": query_value}})
                else:
                    raise SearchException(_(f"Unknown number comparator: '{self.comparator}'"))

            elif field.value_type == Value.TYPE_DATETIME:
                utc_range = calculate_utc_range(org, self.value)

                if self.comparator == "=":
                    es_query &= es_Q(
                        "range",
                        **{"fields.datetime": {"gte": utc_range[0].isoformat(), "lt": utc_range[1].isoformat()}},
                    )
                elif self.comparator == ">":
                    es_query &= es_Q("range", **{"fields.datetime": {"gte": utc_range[1].isoformat()}})
                elif self.comparator == ">=":
                    es_query &= es_Q("range", **{"fields.datetime": {"gte": utc_range[0].isoformat()}})
                elif self.comparator == "<":
                    es_query &= es_Q("range", **{"fields.datetime": {"lt": utc_range[0].isoformat()}})
                elif self.comparator == "<=":
                    es_query &= es_Q("range", **{"fields.datetime": {"lt": utc_range[1].isoformat()}})
                else:
                    raise SearchException(_(f"Unknown datetime comparator: '{self.comparator}'"))

            elif field.value_type in (Value.TYPE_STATE, Value.TYPE_DISTRICT, Value.TYPE_WARD):
                query_value = self.value.lower()

                if field.value_type == Value.TYPE_WARD:
                    field_name = "fields.ward"
                elif field.value_type == Value.TYPE_DISTRICT:
                    field_name = "fields.district"
                elif field.value_type == Value.TYPE_STATE:
                    field_name = "fields.state"
                else:  # pragma: no cover
                    raise SearchException(_(f"Unknown location type: '{field.value_type}'"))

                if self.comparator == "=":
                    field_name += "_keyword"
                    es_query &= es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(_(f"Unsupported comparator '{self.comparator}' for location field"))

            else:  # pragma: no cover
                raise SearchException(_(f"Unrecognized contact field type '{field.value_type}'"))

            return es_Q("nested", path="fields", query=es_query)

        elif prop_type == ContactQuery.PROP_ATTRIBUTE:
            query_value = self.value.lower()

            field_key = field.key

            if field_key == "name":
                if self.comparator == "=":
                    field_name = "name.keyword"
                    es_query = es_Q("term", **{field_name: query_value})
                elif self.comparator == "~":
                    field_name = "name"
                    es_query = es_Q("match", **{field_name: query_value})
                else:
                    raise SearchException(_(f"Unknown attribute comparator: '{self.comparator}'"))
            elif field_key == "id":
                es_query = es_Q("ids", **{"values": [query_value]})
            elif field_key == "language":
                if self.comparator == "=":
                    field_name = "language"
                    es_query = es_Q("term", **{field_name: query_value})
                else:
                    raise SearchException(_(f"Unknown attribute comparator: '{self.comparator}'"))
            elif field_key == "created_on":
                utc_range = calculate_utc_range(org, self.value)
                if self.comparator == "=":
                    es_query = es_Q(
                        "range", **{"created_on": {"gte": utc_range[0].isoformat(), "lt": utc_range[1].isoformat()}}
                    )
                elif self.comparator == ">":
                    es_query = es_Q("range", **{"created_on": {"gte": utc_range[1].isoformat()}})
                elif self.comparator == ">=":
                    es_query = es_Q("range", **{"created_on": {"gte": utc_range[0].isoformat()}})
                elif self.comparator == "<":
                    es_query = es_Q("range", **{"created_on": {"lt": utc_range[0].isoformat()}})
                elif self.comparator == "<=":
                    es_query = es_Q("range", **{"created_on": {"lt": utc_range[1].isoformat()}})
                else:
                    raise SearchException(_(f"Unknown created_on comparator: '{self.comparator}'"))
            else:  # pragma: no cover
                raise SearchException(_(f"Unknown attribute field '{field}'"))
            return es_query

        elif prop_type == ContactQuery.PROP_SCHEME:
            query_value = self.value.lower()
            es_query = es_Q("term", **{"urns.scheme": field.lower()})

            if org.is_anon:
                return es_Q("ids", **{"values": [-1]})
            else:
                if self.comparator == "=":
                    es_query &= es_Q("term", **{"urns.path.keyword": query_value})
                elif self.comparator == "~":
                    es_query &= es_Q("match_phrase", **{"urns.path": query_value})
                else:
                    raise SearchException(_(f"Unknown scheme comparator: '{self.comparator}'"))

                return es_Q("nested", path="urns", query=es_query)
        else:  # pragma: no cover
            raise SearchException(_(f"Unrecognized contact field type '{prop_type}'"))