# Copyright DataStax, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import math from gremlin_python.process.traversal import P from cassandra.util import Distance __all__ = ['GeoP', 'TextDistanceP', 'Search', 'GeoUnit', 'Geo', 'CqlCollection'] class GeoP(object): def __init__(self, operator, value, other=None): self.operator = operator self.value = value self.other = other @staticmethod def inside(*args, **kwargs): return GeoP("inside", *args, **kwargs) def __eq__(self, other): return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other def __repr__(self): return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str( self.value) + "," + str(self.other) + ")" class TextDistanceP(object): def __init__(self, operator, value, distance): self.operator = operator self.value = value self.distance = distance @staticmethod def fuzzy(*args): return TextDistanceP("fuzzy", *args) @staticmethod def token_fuzzy(*args): return TextDistanceP("tokenFuzzy", *args) @staticmethod def phrase(*args): return TextDistanceP("phrase", *args) def __eq__(self, other): return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.distance == other.distance def __repr__(self): return self.operator + "(" + str(self.value) + "," + str(self.distance) + ")" class Search(object): @staticmethod def token(value): """ Search any instance of a certain token within the text property targeted. :param value: the value to look for. """ return P('token', value) @staticmethod def token_prefix(value): """ Search any instance of a certain token prefix withing the text property targeted. :param value: the value to look for. """ return P('tokenPrefix', value) @staticmethod def token_regex(value): """ Search any instance of the provided regular expression for the targeted property. :param value: the value to look for. """ return P('tokenRegex', value) @staticmethod def prefix(value): """ Search for a specific prefix at the beginning of the text property targeted. :param value: the value to look for. """ return P('prefix', value) @staticmethod def regex(value): """ Search for this regular expression inside the text property targeted. :param value: the value to look for. """ return P('regex', value) @staticmethod def fuzzy(value, distance): """ Search for a fuzzy string inside the text property targeted. :param value: the value to look for. :param distance: The distance for the fuzzy search. ie. 1, to allow a one-letter misspellings. """ return TextDistanceP.fuzzy(value, distance) @staticmethod def token_fuzzy(value, distance): """ Search for a token fuzzy inside the text property targeted. :param value: the value to look for. :param distance: The distance for the token fuzzy search. ie. 1, to allow a one-letter misspellings. """ return TextDistanceP.token_fuzzy(value, distance) @staticmethod def phrase(value, proximity): """ Search for a phrase inside the text property targeted. :param value: the value to look for. :param proximity: The proximity for the phrase search. ie. phrase('David Felcey', 2).. to find 'David Felcey' with up to two middle names. """ return TextDistanceP.phrase(value, proximity) class CqlCollection(object): @staticmethod def contains(value): """ Search for a value inside a cql list/set column. :param value: the value to look for. """ return P('contains', value) @staticmethod def contains_value(value): """ Search for a map value. :param value: the value to look for. """ return P('containsValue', value) @staticmethod def contains_key(value): """ Search for a map key. :param value: the value to look for. """ return P('containsKey', value) @staticmethod def entry_eq(value): """ Search for a map entry. :param value: the value to look for. """ return P('entryEq', value) class GeoUnit(object): _EARTH_MEAN_RADIUS_KM = 6371.0087714 _DEGREES_TO_RADIANS = math.pi / 180 _DEG_TO_KM = _DEGREES_TO_RADIANS * _EARTH_MEAN_RADIUS_KM _KM_TO_DEG = 1 / _DEG_TO_KM _MILES_TO_KM = 1.609344001 MILES = _MILES_TO_KM * _KM_TO_DEG KILOMETERS = _KM_TO_DEG METERS = _KM_TO_DEG / 1000.0 DEGREES = 1 class Geo(object): @staticmethod def inside(value, units=GeoUnit.DEGREES): """ Search any instance of geometry inside the Distance targeted. :param value: A Distance to look for. :param units: The units for ``value``. See GeoUnit enum. (Can also provide an integer to use as a multiplier to convert ``value`` to degrees.) """ return GeoP.inside( value=Distance(x=value.x, y=value.y, radius=value.radius * units) )