Ashika Umanga Umagiliya
Ashika Umanga Umagiliya

Reputation: 9178

Hibernate Search/Lucene : String field cannot be used for sorting "indexed with multiple values per document, use SORTED_SET instead"

I have following model .

public class FeatureMeta {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(unique=true)
    private String uri;

    @Column
    @Field
    private String name;

    @Field
    @Column
    private String businessDesc;

    @Field
    @Column
    private String logicalDesc;

    .
    .

}

I am trying to sort the documents by "name" as follows :

org.hibernate.search.jpa.FullTextQuery jpaQuery =
                    fullTextEntityManager.createFullTextQuery(aggrBuilder.build(), FeatureMeta.class);
.
.    

SortFieldContext sortCtx = queryBuilder.sort().byField("name",SortField.Type.STRING);
jpaQuery.setSort(sortCtx.createSort());
.

But Lucene throws following exception ?

java.lang.IllegalStateException: Type mismatch: name was indexed with multiple values per document, use SORTED_SET instead at org.apache.lucene.uninverting.FieldCacheImpl$SortedDocValuesCache.createValue(FieldCacheImpl.java:678) at org.apache.lucene.uninverting.FieldCacheImpl$Cache.get(FieldCacheImpl.java:189) at org.apache.lucene.uninverting.FieldCacheImpl.getTermsIndex(FieldCacheImpl.java:646) at org.apache.lucene.uninverting.FieldCacheImpl.getTermsIndex(FieldCacheImpl.java:626) at org.apache.lucene.uninverting.UninvertingReader.getSortedDocValues(UninvertingReader.java:256) at org.apache.lucene.index.DocValues.getSorted(DocValues.java:262) at org.apache.lucene.search.FieldComparator$TermOrdValComparator.getSortedDocValues(FieldComparator.java:762) at org.apache.lucene.search.FieldComparator$TermOrdValComparator.getLeafComparator(FieldComparator.java:767) at org.apache.lucene.search.FieldValueHitQueue.getComparators(FieldValueHitQueue.java:183) at org.apache.lucene.search.TopFieldCollector$SimpleFieldCollector.getLeafCollector(TopFieldCollector.java:164) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:812) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:535) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:523) at org.hibernate.search.query.engine.impl.LazyQueryState.search(LazyQueryState.java:103)

Any tips?

Upvotes: 0

Views: 1433

Answers (1)

yrodiere
yrodiere

Reputation: 9977

EDIT: Actually, before anything else you should check which analyzer you are using on the name field. The analyzer probably has a tokenizer, which will result in multi-valued fields, which cannot be sorted on. Try adding a different field for sorting, and use an analyzer with a KeywordTokenizer on this field:

@AnalyzerDef(name = "sort_analyzer",
   tokenizer = @TokenizerDef(factory = KeywordTokenizerFactory.class),
   filters = {
       @TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
       @TokenFilterDef(factory = LowerCaseFilterFactory.class)
   }
)
public class FeatureMeta {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(unique=true)
    private String uri;

    @Column
    @Field
    @Field(name = "name_sort", analyzer = @Analyzer(definition = "sort_analyzer"))
    private String name;

    @Field
    @Column
    private String businessDesc;

    @Field
    @Column
    private String logicalDesc;

    .
    .

}

Then sort on this new field, instead of the default one:

SortFieldContext sortCtx = queryBuilder.sort().byField("name_sort",SortField.Type.STRING);

Original answer (the points I made are still valid):

Not sure what causes the exception in your case, but try fixing these issues in your code:

  1. Add a @SortableField annotation on the name property
  2. Do not use queryBuilder.sort().byField("name",SortField.Type.STRING), just use queryBuilder.sort().byField("name")

If it doesn't work, maybe you should try to wipe your indexes and reindex.

Upvotes: 1

Related Questions