Solr 3.6 will have an interesting new feature for currency handling called solr.CurrencyField. Why do we need this when you can just use float for currency handling? I this post you'll see why this feature is going to be useful.
Lets start with the field type configuration, which is quite typical when it comes to Solr. To the schema.xml file we need to add another field type declaration, like the following:
<fieldType class="solr.CurrencyField" name="currencyField" defaultCurrency="USD" currencyConfig="currencyExchange.xml" />
In the above configuration we see two additional attributes (compared to the usual type definition) that define currencyField behavior. First we see the defaultCurrency attribute, which defines the default currency for a given field. It defines in which form data will be written into the index (change of this attribute value requires reindexing). The second attribute, the currencyConfig defines an exchange file. It's worthwhile to remember that using the second parameter only makes sense with the default exchange provider (FileExchangeRateProvided) distributed with Solr. But let’s take a look at the currencyExchange.xml file:
Exchange configuration file for FileExchangeRateProvider
So now, lets look at the contents of the currencyExchange.xml file which provides the exchange rates for the default exchange provider:
<currencyConfig version="1.0"> <rates> <rate from="USD" to="PLN" rate="3.1"/> <rate from="EUR" to="PLN" rate="2.5"/> <rate from="USD" to="EUR" rate="2.5"/> </rates> </currencyConfig>
As you can see the structure is quite simple, we define the base currency (from), output currency (to) and the exchange rate (rate). So it’s quite simple
In order to index the data with the defined currencyField we should specify the value and the currency prefixed with a comma character. For example:
Querying is more or less like indexing. You have to pass two pieces of information to Solr – the value and currency. Let’s look at the two example filters using currency, the first one with a simple term query and the second one a range query:
fq=price:29.99,PLN fq=price:[10.00 TO 29.99,EUR]
As you can see, after setting the value (or range) we have to specify the comma character and the currency we are interested in. Whats more, we are not bound to the default currency – we can query other currencies as long as we have the exchange rate defined. This means that Solr will make the exchange calculation for us. Please remember, that for now, the values returned in the results will only contain the default currency and there is no way to change that behavior.
Your own currency provider
In addition to the default exchange provider, Solr will enable us to plug in our own implementation. In order to do that we need to develop a class that implements org.apache.solr.schema.ExchangeRateProvider interface and let Solr know by passing the class name as the value of providerClass attribute defined for our currency type. Assuming that we have the class pl.solr.schema.DynamicRateExchangeProvider that implements the mentioned interface and we would like to use that class, our field type definition would look something like that:
<fieldType class="solr.CurrencyField" name="currencyField" defaultCurrency="USD" providerClass="pl.solr.schema.DynamicRateExchangeProvider" />
I like this feature as we are not bound to the XML exchange file, but we can develop our own implementation which for example use webservice to dynamically read data from some external source.
What’s left to implement ?
When the post was published you could not use range faceting on fields based on CurrencyField type.
To sum up
In my opinion the CurrencyField is a functionality worth waiting for. Instead of calculating exchange in our application we can let Solr do that for us. In addition to that we will be able to plug in our own implementations of exchange providers, which will enable us to write connectors to different systems and just watch how Solr does all the work for us