Indexing: Numerical Type Conversion


  • The TryConvert() method can be used to safely convert values to numerical types.

  • Learn more about how numbers are stored in RavenDB here.

  • In this page:


Syntax

The following methods are used to convert values into one of the common primitive numerical types - int, long, float, or double. They are called from within the Map or Reduce functions of the index. If the submitted value cannot be converted to the specified type, these methods return null.

In LINQ syntax, use TryConvert<T>():

protected T? TryConvert<T>(object value)
Parameter Type Description
T Generic type parameter The numerical type to which you want to convert your value. Possible values:
- int
- long
- float
- double
value object The value you want to convert, such as a document field. If you pass a string or object, the method will attempt to parse it for a numerical value.

In JavaScript syntax, use tryConvertToNumber().

tryConvertToNumber(value)
Parameter Type Description
value object The value you want to convert, such as a document field. If you pass a string or object, the method will attempt to parse it for a numerical value.

Examples

The class Item has fields of type int, long, float, double, string, and an object field of type Company. The following indexes take an Item entity and attempt to convert each of its fields into the corresponding type. In case of failure, the field is indexed with value -1 instead.

public class TryConvertIndexLINQ : AbstractIndexCreationTask<Item>
{
    public TryConvertIndexLINQ()
    {
        Map = items => from item in items
                       select new
                       {
                           DoubleValue = TryConvert<double>(item.DoubleValue) ?? -1,
                           FloatValue = TryConvert<float>(item.FloatValue) ?? -1,
                           LongValue = TryConvert<long>(item.LongValue) ?? -1,
                           IntValue = TryConvert<int>(item.IntValue) ?? -1,
                           StringValue = TryConvert<double>(item.StringValue) ?? -1,
                           ObjectValue = TryConvert<long>(item.ObjectValue) ?? -1
                       };
    }
}
public class TryConvertIndexJS : AbstractJavaScriptIndexCreationTask
{
    public TryConvertIndexJS()
    {
        Maps = new HashSet<string>
        {
            @"map('Items', function (item) {
                return {
                    DoubleValue: tryConvertToNumber(item.DoubleValue) || -1,
                    FloatValue: tryConvertToNumber(item.FloatValue) || -1,
                    LongValue: tryConvertToNumber(item.LongValue) || -1,
                    IntValue: tryConvertToNumber(item.IntValue) || -1,
                    StringValue: tryConvertToNumber(item.StringValue) || -1,
                    ObjectValue: tryConvertToNumber(item.ObjectValue) || -1
                };
            })"
        };
    }
}
public class Item
{
    public double DoubleValue { get; set; }
    public float FloatValue { get; set; }
    public long LongValue { get; set; }
    public int IntValue { get; set; }
    public string StringValue { get; set; }
    public Company ObjectValue { get; set; }
}

This next index takes the string field Employee.Address.PostalCode and attempts to convert it to long.

The query below it finds all employees that do not have a valid PostalCode field - whether because the employee does not have a postal code or because the value could not be converted to a valid long.

public class Employees_ByPostalCode : AbstractIndexCreationTask<Employee>
{
    public class Result {
        public long PostalCode { get; set; }
    }

    public Employees_ByPostalCode()
    {
        Map = employees => from employee in employees
                           select new Result
                           {
                               PostalCode = TryConvert<long>(employee.Address.PostalCode) ?? -1
                           };
    }
}
Query:

List<Employee> employeesWithoutPostalCode = session
    .Query<Employees_ByPostalCode.Result, Employees_ByPostalCode>()
    .Where(x => x.PostalCode == -1)
    .OfType<Employee>()
    .ToList();