Hibernate Search with special characters

Hi. I’m using the hibernate full-text search on my application. My problem is that I could not search if the search string has some special characters. For example, the search strings are like that “042974/UzGTL” or “UzGTL-CON-1556/174278”, hibernate search returns empty response. If I look for “UzGTL”,
I can get expected responses, such as

UzGTL-CON-1556/174278
UzGTL-CON-1465/043158
046562/UzGTL-CON-1501
2074404/UzGTL-CON-1520
042978/UzGTL-CON-1462
042976/UzGTL-CON-1459
UzGTL-CON-1510 / 2053510
169053/UzGTL-CON-1492
042974/UzGTL-CON-1457

but if I look for “UzGTL-”, then it’ll return empty response.

I also tried to solve with ASCIIFoldingFilterFactory. But it didn’t worked. Could you help me to find what is wrong with my code? Thanks for any help.

**The field I need to search is “code

@Indexed
@Getter
@Setter
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "contracts")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED, withModifiedFlag = true)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class _Contract extends _Entity {


    @AnalyzerDef(name = "searchTextAnalyzer",
            tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
            filters = {@TokenFilterDef(factory = LowerCaseFilterFactory.class),
                       @TokenFilterDef(factory = ASCIIFoldingFilterFactory.class)})
    @Fields(value = {@Field(analyze = Analyze.YES, bridge = @FieldBridge(impl = StringBridge.class)),
            @Field(analyze = Analyze.NO, name = "codeSort", index = org.hibernate.search.annotations.Index.YES)})
    @SortableField(forField = "codeSort")
    @Column(unique = true)
    private String code;

Query execution is below

 SearchFilter searchFilter = new SearchFilter();
  if (filter.has("contractCode"))
            searchFilter.and("code", QueryParser.escape(filter.getString("contractCode")).trim() + "*");
        QueryParser parser = new QueryParser("search", searchFactory().getAnalyzer(_Contract.class));
        parser.setLowercaseExpandedTerms(true);

        org.apache.lucene.search.Query luceneQuery = parser.parse(searchFilter.toString());
        FullTextQuery fullTextQuery = fullTextSession().createFullTextQuery(luceneQuery, _Contract.class);
        fullTextQuery.initializeObjectsWith(ObjectLookupMethod.SECOND_LEVEL_CACHE, DatabaseRetrievalMethod.QUERY);
        fullTextQuery.setFirstResult(filter.getStart());
        fullTextQuery.setMaxResults(filter.getSize());

I use Lucene.

Hello,

This is not how analyzer definitions work. The analyzer definition should go on your class. Then you should use @Field(analyzer = @Analyzer(definition = "searchTextAnalyzer")) in your field definition to actually use the analyzer. See this section of the documentation for more information.

Don’t forget to reindex your data before you try to search again.

I did as you said. I reindexed too. But anyway it returned empty response

@Indexed
@Getter
@Setter
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "contracts")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED, withModifiedFlag = true)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@AnalyzerDef(name = "searchTextAnalyzer",
        tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
        filters = {@TokenFilterDef(factory = LowerCaseFilterFactory.class), @TokenFilterDef(factory = ASCIIFoldingFilterFactory.class)})
public class _Contract extends _Entity {

    @Fields(value = {@Field(analyze = Analyze.YES, index = Index.YES, bridge = @FieldBridge(impl = StringBridge.class), analyzer = @Analyzer(definition = "searchTextAnalyzer")),
            @Field(analyze = Analyze.NO, name = "codeSort", index = org.hibernate.search.annotations.Index.NO)})
    @SortableField(forField = "codeSort")
    @Column(unique = true)
    private String code;

What does luceneQuery.toString() return?

It does “code:UzGTL\-” , if I look for "UzGTL-"

It looks like your terms were not analyzed properly by your query parser. They should be lowercased, at the very least. What does searchFilter.toString() return?

On a side note, you could also use the Hibernate Search DSL to build your queries.

It worked. Thanks a lot :slightly_smiling_face: