Handling multiple currencies

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.

How to do it...

  1. Let's start with creating a sample index structure by modifying the 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" />
  2. In addition to this, we need to provide the definition for the type the 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" />
  3. Another file that we need to create is the 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>
  4. Now we can index some example data. For the usage of this recipe, I decided to index the following documents:
    <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>
  5. Now, let's check if this works. Our second document costs 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.

How it works...

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:

  • EUR
  • HKD
  • GBP

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.

Note

Note that in order for Solr to be able to handle currency exchange between two currencies, we need to provide the direct conversion rate between these two currencies.

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.

There's more...

You can also have the exchange rates updated automatically by specifying the currency provider.

Setting up your own 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 format

So, 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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.74.25