You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@lucene.apache.org by Phil Herold <Ph...@d-wise.com> on 2014/01/22 17:25:25 UTC

Case-insensitive sorting - Lucene 4

We're trying to convert an application from Lucene 3.6 to the current release. We used to be able to pass the result of the static method below as the FieldComparator in a SortField constructor. This code doesn't compile with the latest release, but in converting it, we've been unable to get the setNextReader() and copy() methods to "do the right thing" (whatever that is). Has anyone done something like this? Maybe we're just totally off-base (and were before, though it seemed to work).

Thanks.

--
Phil

package com.foo.bar;

import java.io.IOException;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.FieldComparatorSource;

/**
* Lucene FieldComparator for case-insensitive sorting.
*/
public class CaseInsensitiveStringComparator extends FieldComparator<String> {

   private final String[] values;
   private String[] currentReaderValues;
   private final String field;
   private String bottom;

   /**
    * Private constructor. The static method below is used.
    * @param numHits int
    * @param field String
    * @param reverse boolean
    */
   private CaseInsensitiveStringComparator(int numHits, String field) {
      values = new String[numHits];
      this.field = field;
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#compare(int, int)
    */
   @Override
   public int compare(int slot1, int slot2) {
      final String val1 = values[slot1];
      final String val2 = values[slot2];
      int retVal;
      if (val1 == null) {
         if (val2 == null) {
            retVal = 0;
         }
         retVal = -1;
      }
      else if (val2 == null) {
         retVal = 1;
      }
      else {
         retVal = String.CASE_INSENSITIVE_ORDER.compare(val1, val2);
      }
      return retVal;
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#compareBottom(int)
    */
   @Override
   public int compareBottom(int doc) {
      final String val2 = currentReaderValues[doc];
      int retVal;
      if (bottom == null) {
         if (val2 == null) {
            retVal = 0;
         }
         retVal = -1;
      }
      else if (val2 == null) {
         retVal = 1;
      }
      else {
         retVal = bottom.compareTo(val2);
      }
      return retVal;
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#copy(int, int)
    */
   @Override
   public void copy(int slot, int doc) {
      values[slot] = currentReaderValues[doc];
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#setNextReader(org.apache.lucene.index.IndexReader, int)
    */
   @Override
   public void setNextReader(IndexReader reader, int docBase) throws IOException {
      currentReaderValues = FieldCache.DEFAULT.getStrings(reader, field);
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#setBottom(int)
    */
   @Override
   public void setBottom(final int bottom) {
      this.bottom = values[bottom];
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#value(int)
    */
   @Override
   public String value(int slot) {
      return values[slot];
   }

   /**
    * (override)
    * @see org.apache.lucene.search.FieldComparator#compareValues(java.lang.Object, java.lang.Object)
    */
   @Override
   public int compareValues(String val1, String val2) {
      int retVal;
      if (val1 == null) {
         if (val2 == null) {
            retVal = 0;
         }
         retVal = -1;
      }
      else if (val2 == null) {
         retVal = 1;
      }
      else {
         retVal = String.CASE_INSENSITIVE_ORDER.compare(val1, val2);
      }
      return retVal;
   }

   /**
    * Static method to create the FieldComparator.
    * @param fieldName String
    * @param numHits int
    * @param reverse boolean
    * @return FieldComparatorSource
    */
   @SuppressWarnings("serial")
   public static FieldComparatorSource getFieldComparatorSource(final String fieldName, final int numHits) {
      return new FieldComparatorSource() {

         @Override
         public FieldComparator<String> newComparator(String arg0, int arg1, int arg2, boolean arg3) throws IOException {
            return new CaseInsensitiveStringComparator(numHits, fieldName);
         }

      };
   }
}