Differences between revisions 13 and 14
Revision 13 as of 2013-06-02 11:21:08
Size: 8566
Comment: fixed markup on FileExchangeProvider paragraph
Revision 14 as of 2016-12-20 21:49:07
Size: 734
Comment: remove outdated content; point users to Ref Guide
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
<!> [[Solr3.6]]

<<TableOfContents>>

CurrencyField is an advanced field type indexing a monetary value as both value and currency. It lets e.g. an e-commerce site display and query prices in many currencies, while only indexing the price in one field/currency.

The field type is backed by a pluggable !ExchangeRateProvider. The provider shipping with Solr as default is the {{{FileExchangeRateProvider}}}. Changes in exchange rates from the provider does not require re-indexing, since all conversions are done query-time. You simply choose for each document which currency to index, and this will be fixed.

= Configuration =

See example schema for example of how to use the field type. The field type and field is defined in schema.xml as follows:
{{{
  <dynamicField name="*_c" type="currency" />

  <fieldType name="currency" class="solr.CurrencyField"
             precisionStep="8" currencyConfig="currency.xml" defaultCurrency="EUR" />

  <dynamicField name="*_c" type="currency" />
{{{#!wiki important
This page exists for the Solr Community to share Tips, Tricks, and Advice about
[[https://cwiki.apache.org/solr/Working+with+Currencies+and+Exchange+Rates|Currency fields in Solr]].
 
Reference material previously located on this page has been migrated to the
[[https://cwiki.apache.org/solr/|Official Solr Reference Guide]].
If you need help, please consult the Reference Guide for the version of Solr you are using
for the specific details about using [[https://cwiki.apache.org/solr/Working+with+Currencies+and+Exchange+Rates|this feature]].
 
If you'd like to share information about how you use this feature, please [[FrontPage#How_to_edit_this_Wiki|add it to this page]].
/* cwikimigrated */
Line 20: Line 13:

The {{{defaultCurrency}}} will be used anytime the field is used with values that do not specify and explicit currency. If unspecified the default {{{defaultCurrency}}} is {{{USD}}}. Note that defaultCurrency cannot be changed unless followed by a full re-index.

The {{{precisionStep}}} is passed on to the !TrieLong sub-field. Value "8" gives faster range queries for currencies. If you don't need that, you can save some index space using "0".

Other !FieldType options for !CurrencyField depend on the !ExchangeRateProvider used. In this example !FileExchangeRateProvider uses the {{{currencyConfig}}} option.

= ExchangeRateProviders =

You may plug in your own provider class through implementing the interface {{{ExchangeRateProvider}}}. It may be backed by a web-service, by a flat file, a DB or what you have.

You specify which provider class to use through the parameter {{{providerClass}}} on the fieldType.
If no provider is specified in the fieldType config, {{{FileExchangeRateProvider}}} is used as default.

== FileExchangeRateProvider ==

This is the default provider used if {{{providerClass}}} is not specified. It requires one parameter {{{currencyConfig}}} which should point to an XML file containing conversion information (see below). This config is looked up through Solr's !ResourceLoader.

{{{
   <!-- FileExchangeRateProvider Example
        Parameters:
          currencyConfig: name of an xml file holding exhange rates (mandatory)
   -->
  <fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD"
             providerClass="solr.FileExchangeRateProvider"
             currencyConfig="currency.xml"
   />
}}}

The example {{{currency.xml}}} file in "conf" folder shows how the config could look. Here's an example:

{{{
<currencyConfig version="1.0">
  <rates>
    <!-- Example -->
    <rate from="USD" to="JPY" rate="81.29"/>

    <!-- Fake rates for testing -->
    <rate from="USD" to="EUR" rate="2.5"/>
    <rate from="USD" to="GBP" rate="0.5"/>
    <rate from="EUR" to="GBP" rate="0.5"/>

    <!-- Asymmetric rate -->
    <rate from="EUR" to="USD" rate="0.5"/>
  </rates>
</currencyConfig>
}}}

Note that you need a rate entry between every two pairs of currencies you will index or query. So if you handle USD, EUR and GBP, you need USD->EUR, USD->GBP and EUR->GBP, so that all possible conversions can be done. If you only index one currency (say USD) but want to query or convert multiple, it is enough to have rates between USD and all currencies you'll query or display.

By default the rate will be symmetrical, but you may override this by explicitly specifying the reverse rate.

Replication is supported, given that you explicitly configure replication for {{{currency.xml}}}. Upon the arrival of a new version of currency.xml, Solr slaves will do a core reload and begin using the new exchange rates. See [[SolrReplication#How_are_configuration_files_replicated.3F|SolrReplication]] for more. SolrCloud is also supported since we use !ResourceLoader to load the file.

== OpenExchangeRatesOrgProvider ==
<!> [[Solr4.0]]

This provider downloads and parses the freely available exchange rates from openexchangerates.org, giving rates between USD and 158 currencies, updated hourly. The rates are symmetrical only. Rates between any two currencies are calculated using USD as common base. Sample fieldType configuration:

{{{
   <!-- OpenExchangeRatesOrgProvider Example
        Parameters:
          ratesFileLocation: URL or file path to rates JSON file (mandatory)
          refreshInterval: Number of minutes between each rates fetch (default: 1440, min: 60)
   -->
  <fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD"
             providerClass="solr.OpenExchangeRatesOrgProvider"
             refreshInterval="60"
             ratesFileLocation="http://internal.server/rates.json"
   />
}}}

This tells the CurrencyField to use the !OpenExchangeRates provider with the rates JSON file loaded from a local web server, refreshed every hour.

'''NOTE:''' Up to Solr 4.1, the {{{ratesFileLocation}}} property was not mandatory, and defaulted to {{{http://openexchangerates.org/latest.json}}}, But due to policy changes at openexchangerates.org this generic URL has not worked since June 2012, so specifying a specific URL is now mandatory. See the [[https://openexchangerates.org/documentation|OER Developer Documentation]] for more details.

= Indexing =

When you index e.g. a price, you specify value and currency separated by comma. We use the dynamicField {{{*_c}}} in our examples:
{{{
<doc>
  <field name="id">1</field>
  <field name="myprice_c">1.00,USD</field>
</doc>
}}}

Here, 1.00,USD is assumed to mean $1.00. Note that regardless of the currency being indexed, you must encode the value as a floating point value (with a decimal point.) The fractional portion of the floating point value is interpreted based upon the currency, via Currency.getDefaultFractionDigits().


= Querying =
The !CurrencyField supports both point queries and range queries. Here are some valid money queries. Assume default currency is {{{USD}}}.
In the example schema there is a copyField from "price" to "price_c", meaning that you can test this on the example data:
{{{
# Both of these will query for USD 25.00 since USD is default
price_c:25.00,USD
price_c:25.00

# Both of these will query for values under USD 10.00 since USD is default
price_c:[* TO 10.00,USD]
price_c:[* TO 10.00]

price_c:[10.00,EUR TO 100.00,EUR]
price_c:10.00,NOK
}}}

Begining with [[Solr4.2]] Currency values can also be used in functions. By default, specifying a !CurrencyField in a function results in values corrisponding to the most granular precision of the defualt currency (eg: for USD, the most granular precision is cents), but there is also a {{{currency()}}} function that can be wrapped arround currency fields to generate values corrisponding to the natural value in either the default currency, or a user specified currency.

For example, assuming {{{price_c}}} is a !CurrencyField configured with the {{{defaultCurrency}}} of USD, and assume that with the current !ExchangeRateProvider {{{1.00,EUR == 2.00,USD}}}. The table below shows what various functions would return for documents indexed with various currency values in this field

|| Function || 6.54,USD || 10.00,USD || 5.00,EUR ||
|| price_c || 654 || 1000 || 1000 ||
|| currency(price_c) || 6.54 || 10.0 || 10.0 ||
|| currency(price_c,USD) || 6.54 || 10.0 || 10.0 ||
|| currency(price_c,EUR) || 3.27 || 5.0 || 5.0 ||

= Response Format =

Solr documents will always yield the currency values they were indexed with, regardless of how they were queried for. For example, a set of documents indexed in USD will yield USD values for its Currency fields regardless if you performed queries in EUR.

So, for the display of Currency fields to a user, it may be necessary to perform a second currency conversion once the documents are returned for display purposes. For accuracy, this conversion should apply the same exchange rates in the currency.xml file available to Solr.

Alternatively, the {{{currency()}}} function mentioned above can be used...

{{{
    fl=id,score,price:currency(price_c,EUR)
}}}

= TODO =

 * facet.range is not yet supported for this field type - See [[https://issues.apache.org/jira/browse/SOLR-3218|SOLR-3218]]

This page exists for the Solr Community to share Tips, Tricks, and Advice about Currency fields in Solr.

Reference material previously located on this page has been migrated to the Official Solr Reference Guide. If you need help, please consult the Reference Guide for the version of Solr you are using for the specific details about using this feature.

If you'd like to share information about how you use this feature, please add it to this page.

CurrencyField (last edited 2016-12-20 21:49:07 by CassandraTargett)