def _GetFieldValue(cls, field): """Returns the value of a field as the correct type. Args: field: The field whose value is extracted. If the given field is None, this function also returns None. This is to make it easier to chain with GetFieldInDocument(). Returns: The value of the field with the correct type (float for number fields, datetime.datetime for date fields, etc). Raises: TypeError: if the type of the field isn't recognized. """ if not field: return None value_type = field.value().type() if value_type in search_util.TEXT_DOCUMENT_FIELD_TYPES: return field.value().string_value() if value_type == document_pb.FieldValue.DATE: value = field.value().string_value() return search_util.DeserializeDate(value) if value_type == document_pb.FieldValue.NUMBER: value = field.value().string_value() return float(value) if value_type == document_pb.FieldValue.GEO: value = field.value().geo() return geo_util.LatLng(value.lat(), value.lng()) raise TypeError('No conversion defined for type %s' % value_type)
def ValueOf(self, expression, default_value=None, return_type=None, allow_rank=True): """Returns the value of an expression on a document. Args: expression: The expression string. default_value: The value to return if the expression cannot be evaluated. return_type: The type the expression should evaluate to. Used to create multiple sorts for ambiguous expressions. If None, the expression evaluates to the inferred type or first type of a field it encounters in a document. allow_rank: For expressions that will be used in a sort context, indicate if rank is allowed. Returns: The value of the expression on the evaluator's document, or default_value if the expression cannot be evaluated on the document. Raises: ExpressionEvaluationError: sort expression cannot be evaluated because the expression or default value is malformed. Callers of ValueOf should catch and return error to user in response. QueryExpressionEvaluationError: same as ExpressionEvaluationError but these errors should return query as error status to users. """ expression_tree = Parse(expression) if not expression_tree.getType() and expression_tree.children: expression_tree = expression_tree.children[0] name = query_parser.GetQueryNodeText(expression_tree) schema = self._inverted_index.GetSchema() if (expression_tree.getType() == ExpressionParser.NAME and name in schema): contains_text_result = False for field_type in schema[name].type_list(): if field_type in search_util.TEXT_DOCUMENT_FIELD_TYPES: contains_text_result = True if (schema.IsType(name, document_pb.FieldValue.DATE) and not contains_text_result): if isinstance(default_value, basestring): try: default_value = search_util.DeserializeDate( default_value) except ValueError: raise QueryExpressionEvaluationError( 'Default text value is not appropriate for sort expression \'' + name + '\': failed to parse date \"' + default_value + '\"') result = default_value try: result = self._Eval(expression_tree, return_type=return_type, allow_rank=allow_rank) except _ExpressionError, e: logging.debug('Skipping expression %s: %s', expression, e)
def SortKey(scored_doc): """Return the sort key for a document based on the request parameters.""" field = search_util.GetFieldInDocument( scored_doc.document, sort_spec.sort_expression()) if not field: return default_value string_val = field.value().string_value() if field.value().type() in search_util.NUMBER_DOCUMENT_FIELD_TYPES: return float(string_val) if field.value().type() is document_pb.FieldValue.DATE: return search_util.EpochTime(search_util.DeserializeDate(string_val)) return string_val
def ValueOf(self, expression, default_value=None): """Returns the value of an expression on a document. Args: expression: The expression string. default_value: The value to return if the expression cannot be evaluated. Returns: The value of the expression on the evaluator's document, or default_value if the expression cannot be evaluated on the document. Raises: ExpressionEvaluationError: sort expression cannot be evaluated because the expression or default value is malformed. Callers of ValueOf should catch and return error to user in response. QueryExpressionEvaluationError: same as ExpressionEvaluationError but these errors should return query as error status to users. """ expression_tree = Parse(expression) if not expression_tree.getType() and expression_tree.children: expression_tree = expression_tree.children[0] name = query_parser.GetQueryNodeText(expression_tree) schema = self._inverted_index.GetSchema() if (expression_tree.getType() == ExpressionParser.NAME and schema.IsType(name, document_pb.FieldValue.DATE)): if isinstance(default_value, basestring): try: default_value = search_util.DeserializeDate(default_value) except ValueError: raise QueryExpressionEvaluationError( 'failed to parse date \"' + default_value + '\"') result = default_value try: result = self._Eval(expression_tree) except _ExpressionError, e: logging.debug('Skipping expression %s: %s', expression, e)
def _DateStrToDays(date_str): date = search_util.DeserializeDate(date_str) return search_util.EpochTime(date) / MSEC_PER_DAY