sorting - FieldComparatorSource not working on unoptimized index -


for reason fieldcomparatorsource doesn't work when index not optimized (i deleted documents , re-indexed same data again end segmented index. "not working" meaning compare method never called these re-indexed documents.

i using lucene 3.6.2 hibernate search (which not relevant).

this fieldcomparatorsource. can pass preferred sort order , comparator sorts accordingly. it works optimized index though.

import java.io.ioexception; import java.util.arrays; import java.util.hashmap; import java.util.list; import java.util.map;  import org.apache.lucene.index.indexreader; import org.apache.lucene.search.fieldcache; import org.apache.lucene.search.fieldcomparator; import org.apache.lucene.search.fieldcomparatorsource; import org.hibernate.search.bridge.twowaystringbridge;  import com.google.common.collect.range; import com.google.common.collect.rangemap; import com.google.common.collect.treerangemap;  /**  * provides fieldcomparators doesn't sort normal values sort  * specified preferred values front  *   * can used boolean values (just submit list containing true  * value , fine)  *   * <br>  * <br>  * todo: maybe use fieldcache?: <br>  * <br>  *   * <b>http://lucene.472066.n3.nabble.com/custom-fieldcomparator-and-incorrect-  * sort- order-td561154.html<b> <br>  * <b>http://lucene.apache.org/core/3_6_0/api/all/org/apache/lucene  * /search/fieldcache.html<b> <br>  *   * @author martin braun  */ public class preferencefieldcomparatorsource<t> extends fieldcomparatorsource {      private static final long serialversionuid = -8959374194451783596l;      private final map<t, integer> preference;     private final twowaystringbridge stringbridge;      @safevarargs     public preferencefieldcomparatorsource(twowaystringbridge stringbridge,             t... preferred) {         this(stringbridge, arrays.aslist(preferred));     }      public preferencefieldcomparatorsource(twowaystringbridge stringbridge,             list<t> preferred) {         this(stringbridge, tomap(preferred));     }      public preferencefieldcomparatorsource(twowaystringbridge stringbridge,             map<t, integer> preference) {         this.stringbridge = stringbridge;         this.preference = preference;     }      @override     public fieldcomparator<string> newcomparator(final string fieldname,             int numhits, int sortpos, final boolean reversed)             throws ioexception {         return new fieldcomparator<string>() {              private rangemap<integer, docbasevaluewrapper<string>> values = treerangemap                     .create();             private string bottom;             private rangemap<integer, docbasevaluewrapper<string>> currentreadervalues = treerangemap                     .create();              @override             public int compare(int slot1, int slot2) {                 return this.compare(this.values.get(slot1).get(slot1),                         this.values.get(slot2).get(slot2));             }              @override             public int comparebottom(int doc) throws ioexception {                 return this.compare(this.bottom,                         this.currentreadervalues.get(doc).get(doc));             }              @override             public void copy(int slot, int doc) throws ioexception {                 this.values.get(slot).put(slot,                         this.currentreadervalues.get(doc).get(doc));             }              @override             public void setbottom(int slot) {                 this.bottom = this.values.get(slot).get(slot);             }              @override             public void setnextreader(indexreader reader, int docbase)                     throws ioexception {                 this.currentreadervalues.put(range.closed(docbase, docbase                         + reader.maxdoc()), docbasevaluewrapper.create(docbase,                         fieldcache.default.getstrings(reader, fieldname)));                 this.values.put(                         range.closed(docbase, docbase + reader.maxdoc()),                         docbasevaluewrapper.create(docbase,                                 new string[reader.maxdoc()]));             }              @override             public string value(int slot) {                 return this.values.get(slot).get(slot);             }              private int compare(object first, object second) {                 if (first == null && second == null) {                     return 0;                 } else if (first == null) {                     return 1;                 } else if (second == null) {                     return -1;                 }                 integer firstpos = preferencefieldcomparatorsource.this.preference                         .get(preferencefieldcomparatorsource.this.stringbridge                                 .stringtoobject((string) first));                 integer secondpos = preferencefieldcomparatorsource.this.preference                         .get(preferencefieldcomparatorsource.this.stringbridge                                 .stringtoobject((string) second));                 int firstindex = firstpos != null ? firstpos : -1;                 int secondindex = secondpos != null ? secondpos : -1;                 int result;                 if (firstindex == -1 || secondindex == -1) {                     if (firstindex == secondindex) {                         result = 0;                     } else if (firstindex == -1) {                         result = 1;                     } else {                         result = -1;                     }                 } else {                     result = integer.compare(firstindex, secondindex);                 }                 if (reversed) {                     result *= -1;                 }                 return result;             }          };     }      private static <t> map<t, integer> tomap(list<t> preferred) {         map<t, integer> preference = new hashmap<>();         (int = 0; < preferred.size(); ++i) {             preference.put(preferred.get(i), i);         }         return preference;     }  } 

the utility class easy segmentation.

public class docbasevaluewrapper<t> {      private docbasevaluewrapper(int slotbase,             t[] values) {         this.slotbase = slotbase;         this.values = values;     }      private final int slotbase;     private final t[] values;      public t get(int doc) {         return this.values[doc - slotbase];     }      public void put(int doc, t value) {         this.values[doc - slotbase] = value;     }      public static <t> docbasevaluewrapper<t> create(int slotbase, t[] values) {         return new docbasevaluewrapper<>(slotbase, values);     }  } 

my index looks this:

the index

i fixed it. using fieldcomparatorsource api wrong , handled docs relative 0 instead of handling them relative docbase.

the whole wrapper construct unnecessary.


Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -