Imagine a situation where you run an e-commerce site and sell your products all over the world. One day, you say that you want to calculate the currencies by yourself and have all the goodies that Solr gives you on all the currencies you support. You can, of course, add multiple fields, one for each currency. On the other hand, you can use the new functionality introduced in Solr 4 and create a field that will use the provided currency exchange rates. This recipe will show you how to configure and use multiple currencies using a single field in the index.
schema.xml
file so that the field definition looks like this:<field name="id" type="string" indexed="true" stored="true" required="true" /> <field name="name" type="text_general" indexed="true" stored="true" /> <field name="price" type="currencyField" indexed="true" stored="true" />
price
field is based on (again we add the following to the schema.xml
file):<fieldType class="solr.CurrencyField" name="currencyField" defaultCurrency="USD" currencyConfig="currencyExchange.xml" />
currencyExchange.xml
file, which should be placed in the conf
directory of your collection and contain the following:<?xml version="1.0" ?> <currencyConfig version="1.0"> <rates> <rate from="USD" to="EUR" rate="0.743676" comment="European Euro" /> <rate from="USD" to="HKD" rate="7.801922" comment="HONG KONG Dollar" /> <rate from="USD" to="GBP" rate="0.647910" comment="UNITED KINGDOM Pound" /> </rates> </currencyConfig>
<add> <doc> <field name="id">1</field> <field name="name">Test document one</field> <field name="price">10.10,USD</field> </doc> <doc> <field name="id">2</field> <field name="name">Test document two</field> <field name="price">12.01,USD</field> </doc> </add>
12.01 USD
, and we define the exchange rate for the Euro to 0.743676
. This gives us about 7.5 EUR for the first document, and about 8.9 EUR for the second document. Let's check this by sending the following query to Solr:http://localhost:8983/solr/cookbook/select?q=name:document&fq=price:[8.00,EUR TO 9.00,EUR]
The result returned by Solr is the following:
<?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">1</int> <lst name="params"> <str name="fq">price:[8.00,EUR TO 9.00,EUR]</str> <str name="q">name:document</str> </lst> </lst> <result name="response" numFound="1" start="0"> <doc> <str name="id">2</str> <str name="name">Test document two</str> <str name="price">12.01,USD</str> <long name="_version_">1467445704565719040</long> </doc> </result> </response>
As you can see, we got the document we wanted.
The idea behind the functionality is simple—we create a field based on a certain type and provide a file with the currency exchange rate, that's all. After this, we can query our Solr instance with the use of all the currencies we defined exchange rates for. Now, let's discuss all the preceding configuration changes in detail.
The index structure is very simple; it contains three fields of which one is responsible for holding the price of the document and is based on the currencyField
type. The mentioned type is based on solr.CurrencyField
. Its defaultCurrency
attribute specifies the default currency for all the fields using this type. This is important because Solr will return prices in the defined default currency, no matter what currency is used during the query. The currencyConfig
attribute specifies the name of the file with the exchange rate definition.
Our currencyExchange.xml
file provides the exchange rates for three currencies:
The file should be structured similar to the previous example. This means that each exchange rate should have the from
attribute telling Solr from which currency the exchange will be done, the to
attribute specifying to which currency the exchange will be done, and the rate
attribute specifying the actual exchange rate. In addition to this, it can also have the comment
attribute if we want to include some short comment.
During indexing, we need to specify the currency we want the data to be indexed with. In the previous example, we indexed data with USD. This is done by specifying the price, a comma character, and the currency code after it. So, the 10.10,USD
value will mean 10 dollars and 10 cents in USD.
If you need to reload the currencyExchange.xml
file, you will need to reload the core (or collection) for Solr to see the changes. If you use the master-slave deployment, slave servers will reload the core upon finishing fetching the new index and new version of the currencyExchange.xml
file, which will be loaded (of course, if it is configured to be replicated).
The last thing is the query. As you can see, you can query Solr with currencies different from the one used during indexing. This is possible because of the provided exchange rate file. As you can see, when we use a range
query for a price
field, we specify the value, colon character, and currency code after it. Remember that if you provide a currency code unknown to Solr, it will throw an exception saying that the currency is not known.
You can also have the exchange rates updated automatically by specifying the currency provider.
Specifying the currency exchange rate file is great, but we need to update this file because the exchange rates change constantly. Luckily for us, Solr committers thought about it and gave us the option to provide an exchange rate provider instead of a plain file. The provider is a class responsible for providing the exchange rate data. The default exchange rate provider available in Solr uses exchange rates from http://openexchangerates.org, which are updated hourly. In order to use it, we need to modify our currencyField
field type definition and introduce three new properties (and remove the currencyConfig
property):
providerClass
: This is the class implementing the exchange rates provider, which in our case will be the default available in Solr, which is solr.OpenExchangeRatesOrgProvider
refreshInterval
: This defines how often to refresh the rates (specified in minutes)ratesFileLocation
: This is the location of the file with rates in an open exchange formatSo, the final configuration should look like this:
<fieldType name="currencyField" class="solr.CurrencyField" providerClass="solr.OpenExchangeRatesOrgProvider" refreshInterval="120" ratesFileLocation="http://192.168.10.10/latest.json"/>
You can download the sample exchange file from the http://openexchangerates.org site after creating an account.
52.15.74.25