You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2012/03/10 09:21:34 UTC

svn commit: r1299159 - in /lucene/dev/branches/branch_3x: ./ solr/ solr/core/ solr/core/src/java/org/apache/solr/schema/ solr/core/src/test-files/solr/conf/ solr/core/src/test/org/apache/solr/schema/ solr/example/exampledocs/ solr/example/solr/conf/ so...

Author: janhoy
Date: Sat Mar 10 08:21:34 2012
New Revision: 1299159

URL: http://svn.apache.org/viewvc?rev=1299159&view=rev
Log:
SOLR-2202: Money/Currency FieldType backport

Added:
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/schema/CurrencyField.java
      - copied, changed from r1299083, lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java
      - copied unchanged from r1299083, lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java
    lucene/dev/branches/branch_3x/solr/core/src/test-files/solr/conf/currency.xml
      - copied unchanged from r1299083, lucene/dev/trunk/solr/core/src/test-files/solr/conf/currency.xml
    lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java
      - copied, changed from r1299083, lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java
    lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java
      - copied, changed from r1299083, lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java
    lucene/dev/branches/branch_3x/solr/example/exampledocs/money.xml
      - copied unchanged from r1299083, lucene/dev/trunk/solr/example/exampledocs/money.xml
    lucene/dev/branches/branch_3x/solr/example/solr/conf/currency.xml
      - copied unchanged from r1299083, lucene/dev/trunk/solr/example/solr/conf/currency.xml
Modified:
    lucene/dev/branches/branch_3x/   (props changed)
    lucene/dev/branches/branch_3x/solr/   (props changed)
    lucene/dev/branches/branch_3x/solr/CHANGES.txt
    lucene/dev/branches/branch_3x/solr/core/   (props changed)
    lucene/dev/branches/branch_3x/solr/core/src/test-files/solr/conf/schema.xml
    lucene/dev/branches/branch_3x/solr/example/solr/conf/schema.xml
    lucene/dev/branches/branch_3x/solr/example/solr/conf/velocity/doc.vm

Modified: lucene/dev/branches/branch_3x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/CHANGES.txt?rev=1299159&r1=1299158&r2=1299159&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_3x/solr/CHANGES.txt Sat Mar 10 08:21:34 2012
@@ -107,6 +107,9 @@ New Features
 * SOLR-3033: ReplicationHandler's backup command now supports a 'maxNumberOfBackups' 
   init param that can be used to delete all but the most recent N backups. (Torsten Krah, James Dyer)
 
+* SOLR-2202: Currency FieldType, whith support for currencies and exchange rates
+  (Greg Fodor & Andrew Morrison via janhoy, rmuir, Uwe Schindler)
+
 Optimizations
 ----------------------
 * SOLR-1931: Speedup for LukeRequestHandler and admin/schema browser. New parameter

Copied: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/schema/CurrencyField.java (from r1299083, lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/schema/CurrencyField.java?p2=lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/schema/CurrencyField.java&p1=lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java&r1=1299083&r2=1299159&rev=1299159&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/schema/CurrencyField.java Sat Mar 10 08:21:34 2012
@@ -16,10 +16,11 @@ package org.apache.solr.schema;
  * limitations under the License.
  */
 
-import org.apache.lucene.index.AtomicReaderContext;
-import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.document.Field.Index;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.Field.TermVector;
+import org.apache.lucene.document.Fieldable;
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.SortField;
 import org.apache.solr.common.ResourceLoader;
@@ -29,6 +30,8 @@ import org.apache.solr.response.TextResp
 import org.apache.solr.response.XMLWriter;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.SolrConstantScoreQuery;
+import org.apache.solr.search.function.DocValues;
+import org.apache.solr.search.function.ValueSource;
 import org.apache.solr.search.function.ValueSourceRangeFilter;
 import org.apache.solr.util.plugin.ResourceLoaderAware;
 import org.slf4j.Logger;
@@ -117,21 +120,19 @@ public class CurrencyField extends Field
   }
 
   @Override
-  public IndexableField[] createFields(SchemaField field, Object externalVal, float boost) {
-    CurrencyValue value = CurrencyValue.parse(externalVal.toString(), defaultCurrency);
+  public Fieldable[] createFields(SchemaField field, String externalVal, float boost) {
+    CurrencyValue value = CurrencyValue.parse(externalVal, defaultCurrency);
 
-    IndexableField[] f = new IndexableField[field.stored() ? 3 : 2];
+    Fieldable[] f = new Fieldable[field.stored() ? 3 : 2];
     f[0] = getAmountField(field).createField(String.valueOf(value.getAmount()), boost);
     f[1] = getCurrencyField(field).createField(value.getCurrencyCode(), boost);
 
     if (field.stored()) {
-      org.apache.lucene.document.FieldType customType = new org.apache.lucene.document.FieldType();
-      customType.setStored(true);
       String storedValue = externalVal.toString().trim();
       if (storedValue.indexOf(",") < 0) {
         storedValue += "," + defaultCurrency;
       }
-      f[2] = createField(field.getName(), storedValue, customType, boost);
+      f[2] = createField(field.getName(), storedValue, Store.YES, Index.NO, TermVector.NO, true, null, boost);
     }
 
     return f;
@@ -207,8 +208,7 @@ public class CurrencyField extends Field
     String currencyCode = p1.getCurrencyCode();
     final CurrencyValueSource vs = new CurrencyValueSource(field, currencyCode, parser);
 
-    return new SolrConstantScoreQuery(new ValueSourceRangeFilter(vs,
-            p1.getAmount() + "", p2.getAmount() + "", minInclusive, maxInclusive));
+    return new SolrConstantScoreQuery(new ValueSourceRangeFilter(vs, p1.getAmount() + "", p2.getAmount() + "", minInclusive, maxInclusive));
   }
 
   @Override
@@ -221,12 +221,12 @@ public class CurrencyField extends Field
     }
   }
 
-  public void write(XMLWriter xmlWriter, String name, IndexableField field) throws IOException {
-    xmlWriter.writeStr(name, field.stringValue(), false);
+  public void write(XMLWriter xmlWriter, String name, Fieldable field) throws IOException {
+    xmlWriter.writeStr(name, field.stringValue());
   }
 
   @Override
-  public void write(TextResponseWriter writer, String name, IndexableField field) throws IOException {
+  public void write(TextResponseWriter writer, String name, Fieldable field) throws IOException {
     writer.writeStr(name, field.stringValue(), false);
   }
 
@@ -252,11 +252,11 @@ public class CurrencyField extends Field
       amountValues = amountField.getType().getValueSource(amountField, parser);
     }
 
-    public FunctionValues getValues(Map context, AtomicReaderContext reader) throws IOException {
-      final FunctionValues amounts = amountValues.getValues(context, reader);
-      final FunctionValues currencies = currencyValues.getValues(context, reader);
+    public DocValues getValues(Map context, IndexReader reader) throws IOException {
+      final DocValues amounts = amountValues.getValues(context, reader);
+      final DocValues currencies = currencyValues.getValues(context, reader);
 
-      return new FunctionValues() {
+      return new DocValues() {
         private final int MAX_CURRENCIES_TO_CACHE = 256;
         private final int[] fractionDigitCache = new int[MAX_CURRENCIES_TO_CACHE];
         private final String[] currencyOrdToCurrencyCache = new String[MAX_CURRENCIES_TO_CACHE];
@@ -297,7 +297,7 @@ public class CurrencyField extends Field
           }
 
           long amount = amounts.longVal(doc);
-          int currencyOrd = currencies.ordVal(doc);
+          int currencyOrd = currencies.intVal(doc);
 
           if (currencyOrd == targetCurrencyOrd) {
             return amount;
@@ -489,7 +489,6 @@ class FileExchangeRateProvider implement
     return "["+this.getClass().getName()+" : " + rates.size() + " rates.]";
   }
 
-  @Override
   public String[] listAvailableCurrencies() {
     List<String> pairs = new ArrayList<String>();
     for(String from : rates.keySet()) {
@@ -500,7 +499,6 @@ class FileExchangeRateProvider implement
     return pairs.toArray(new String[1]);
   }
 
-  @Override
   public boolean reload() throws SolrException {
     InputStream is = null;
     Map<String, Map<String, Double>> tmpRates = new HashMap<String, Map<String, Double>>();
@@ -577,7 +575,6 @@ class FileExchangeRateProvider implement
     return true;
   }
 
-  @Override
   public void init(Map<String,String> params) throws SolrException {
     this.currencyConfigFile = params.get(PARAM_CURRENCY_CONFIG);
     if(currencyConfigFile == null) {
@@ -588,7 +585,6 @@ class FileExchangeRateProvider implement
     params.remove(PARAM_CURRENCY_CONFIG);
   }
 
-  @Override
   public void inform(ResourceLoader loader) throws SolrException {
     if(loader == null) {
       throw new SolrException(ErrorCode.BAD_REQUEST, "Needs ResourceLoader in order to load config file");

Modified: lucene/dev/branches/branch_3x/solr/core/src/test-files/solr/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/test-files/solr/conf/schema.xml?rev=1299159&r1=1299158&r2=1299159&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/test-files/solr/conf/schema.xml (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/test-files/solr/conf/schema.xml Sat Mar 10 08:21:34 2012
@@ -393,6 +393,9 @@
 
   <fieldType name="latLon" class="solr.LatLonType" subFieldType="double"/>
 
+  <!-- Currency type -->
+  <fieldType name="currency" class="solr.CurrencyField" currencyConfig="currency.xml"/>
+  <fieldType name="mock_currency" class="solr.CurrencyField" providerClass="org.apache.solr.schema.MockExchangeRateProvider" foo="bar" />
   
   <!-- omitPositions example -->
   <fieldType name="nopositions" class="solr.TextField" omitPositions="true">
@@ -440,6 +443,9 @@
 
    <field name="point10" type="tenD" indexed="true" stored="true" multiValued="false"/>
 
+   <!-- Test currency -->
+   <field name="amount" type="currency" indexed="true" stored="true" multiValued="false"/>
+   <field name="mock_amount" type="mock_currency" indexed="true" stored="true"/>
 
    <!-- test different combinations of indexed and stored -->
    <field name="bind" type="boolean" indexed="true" stored="false"/>

Copied: lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java (from r1299083, lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java?p2=lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java&p1=lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java&r1=1299083&r2=1299159&rev=1299159&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java Sat Mar 10 08:21:34 2012
@@ -16,14 +16,13 @@ package org.apache.solr.schema;
  * limitations under the License.
  */
 
-import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.document.Fieldable;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.core.SolrCore;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import java.util.Arrays;
 import java.util.Random;
 
 /**
@@ -71,13 +70,13 @@ public class CurrencyFieldTest extends S
     FieldType tmp = amount.getType();
     assertTrue(tmp instanceof CurrencyField);
     String currencyValue = "1.50,EUR";
-    IndexableField[] fields = amount.createFields(currencyValue, 2);
+    Fieldable[] fields = amount.createFields(currencyValue, 2);
     assertEquals(fields.length, 3);
 
     // First field is currency code, second is value, third is stored.
     for (int i = 0; i < 3; i++) {
       boolean hasValue = fields[i].readerValue() != null
-              || fields[i].numericValue() != null
+              || fields[i].getBinaryValue() != null
               || fields[i].stringValue() != null;
       assertTrue("Doesn't have a value: " + fields[i], hasValue);
     }
@@ -203,7 +202,7 @@ public class CurrencyFieldTest extends S
     assertU(adoc("id", "3", "mock_amount", "1.00,NOK"));
     assertU(commit());
 
-    assertQ(req("fl", "*,score", "q", "mock_amount:5.0,NOK"),   "//*[@numFound='1']", "//int[@name='id']='1'");
+    assertQ(req("fl", "*,score", "q", "mock_amount:5.0,NOK"), "//*[@numFound='1']", "//int[@name='id']='1'");
     assertQ(req("fl", "*,score", "q", "mock_amount:1.2,USD"), "//*[@numFound='1']",   "//int[@name='id']='2'");
     assertQ(req("fl", "*,score", "q", "mock_amount:0.2,USD"), "//*[@numFound='1']",   "//int[@name='id']='3'");
     assertQ(req("fl", "*,score", "q", "mock_amount:99,USD"),  "//*[@numFound='0']");

Copied: lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java (from r1299083, lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java?p2=lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java&p1=lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java&r1=1299083&r2=1299159&rev=1299159&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java Sat Mar 10 08:21:34 2012
@@ -40,7 +40,6 @@ public class MockExchangeRateProvider im
   private boolean gotArgs = false;
   private boolean gotLoader = false;
   
-  @Override
   public double getExchangeRate(String sourceCurrencyCode, String targetCurrencyCode) {
 //    System.out.println("***** getExchangeRate("+sourceCurrencyCode+targetCurrencyCode+")");
     if(sourceCurrencyCode.equals(targetCurrencyCode)) return 1.0;
@@ -52,26 +51,22 @@ public class MockExchangeRateProvider im
     return result;
   }
 
-  @Override
   public String[] listAvailableCurrencies() {
     return map.keySet().toArray(new String[1]);
   }
 
-  @Override
   public boolean reload() throws SolrException {
     assert(gotArgs == true);
     assert(gotLoader == true);
     return true;
   }
 
-  @Override
   public void init(Map<String,String> args) {
     assert(args.get("foo").equals("bar"));
     gotArgs = true;
     args.remove("foo");
   }
 
-  @Override
   public void inform(ResourceLoader loader) throws SolrException {
     assert(loader != null);
     gotLoader = true;

Modified: lucene/dev/branches/branch_3x/solr/example/solr/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/example/solr/conf/schema.xml?rev=1299159&r1=1299158&r2=1299159&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/example/solr/conf/schema.xml (original)
+++ lucene/dev/branches/branch_3x/solr/example/solr/conf/schema.xml Sat Mar 10 08:21:34 2012
@@ -471,6 +471,15 @@
     See http://wiki.apache.org/solr/SpatialSearch
    -->
     <fieldtype name="geohash" class="solr.GeoHashField"/>
+   <!-- Money/currency field type. See http://wiki.apache.org/solr/MoneyFieldType
+        Parameters:
+          defaultCurrency: Specifies the default currency if none specified. Defaults to "USD"
+          providerClass:   Lets you plug in other exchange backend. Defaults to FileExchangeRateProvider
+                           The FileExchangeRateProvider takes one parameter:
+                             currencyConfig: name of an xml file holding exhange rates
+   -->
+    <fieldType name="currency" class="solr.CurrencyField" currencyConfig="currency.xml" defaultCurrency="USD"/>
+
    <!-- some examples for different languages (generally ordered by ISO code) -->
 
     <!-- Arabic -->
@@ -942,6 +951,7 @@
    <dynamicField name="*_tdt" type="tdate"  indexed="true"  stored="true"/>
    
    <dynamicField name="*_pi"  type="pint"    indexed="true"  stored="true"/>
+   <dynamicField name="*_c"   type="currency" indexed="true"  stored="true"/>
 
    <dynamicField name="ignored_*" type="ignored" multiValued="true"/>
    <dynamicField name="attr_*" type="text_general" indexed="true" stored="true" multiValued="true"/>
@@ -977,6 +987,9 @@
    <copyField source="features" dest="text"/>
    <copyField source="includes" dest="text"/>
    <copyField source="manu" dest="manu_exact"/>
+
+   <!-- Copy the price into a currency enabled field (default USD) -->
+   <copyField source="price" dest="price_c"/>
 	
    <!-- Above, multiple source fields are copied to the [text] field. 
 	  Another way to map multiple source fields to the same 

Modified: lucene/dev/branches/branch_3x/solr/example/solr/conf/velocity/doc.vm
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/example/solr/conf/velocity/doc.vm?rev=1299159&r1=1299158&r2=1299159&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/example/solr/conf/velocity/doc.vm (original)
+++ lucene/dev/branches/branch_3x/solr/example/solr/conf/velocity/doc.vm Sat Mar 10 08:21:34 2012
@@ -2,7 +2,7 @@
 ##do we have a physical store for this product
 #set($store = $doc.getFieldValue('store'))
 #if($store)<div class="map"><img src="http://maps.google.com/maps/api/staticmap?&zoom=12&size=150x80&maptype=roadmap&markers=$doc.getFieldValue('store')&sensor=false" /><div><small><a target="_map" href="http://maps.google.com/?q=$store&amp;source=embed">Larger Map</a></small></div></div>#end
-<div>Price: $!number.currency($doc.getFieldValue('price'))</div>
+<div>Price: #field('price_c')</div>
 <div>Features: #field('features')</div>
 <div>In Stock: #field('inStock')</div>
 <div class="mlt">