2016-03-18 3 views
0

Я индексировали эту сущностьКак игнорировать некоторые символы в Lucene Query (Hibernate Search)

@Entity 
@Indexed 
public class MyBean { 

    @Id 
    private Long id; 

    @Field 
    private String foo; 

    @Field 
    private String bar; 

    @Field 
    private String baz; 

} 

для этой схемы:

+----+-------------+-------------+-------------+ 
| id |  foo  |  bar  |  baz  | 
+----+-------------+-------------+-------------+ 
| 11 | an example | ignore this | ignore this | 
| 12 | ignore this | an e.x.a.m. | ignore this | 
| 13 | not this | not this | not this | 
+----+-------------+-------------+-------------+ 

Мне нужно найти 11 и 12 путем поиска exam.

Я попытался с:

FullTextEntityManager fullTextEntityManager = 
    Search.getFullTextEntityManager(this.entityManager); 

QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory() 
    .buildQueryBuilder().forEntity(MyBean.class).get(); 

Query textQuery = queryBuilder.keyword() 
    .onFields("foo", "bar", "baz").matching("exam").createQuery(); 

fullTextEntityManager.createFullTextQuery(textQuery, MyBean.class).getResultList(); 

, но это только найти объект 11, где мне нужно также 12. Возможно ли это?

ответ

1

Добавление WordDelimiterFilter с CATENATE_ALL флаг в ваш анализ цепи, был бы вероятным решением.

Так реализация анализатора на основе StandardAnalyzer будет выглядеть следующим образом:

public class StandardWithWordDelim extends StopwordAnalyzerBase{ 

    public static final CharArraySet STOP_WORDS_SET = StopAnalyzer.ENGLISH_STOP_WORDS_SET; 

    public StandardWithWordDelim() { 
    } 

    @Override 
    protected TokenStreamComponents createComponents(final String fieldName) { 
     StandardTokenizer src = new StandardTokenizer(); 
     src.setMaxTokenLength(255); 
     TokenStream filter = new StandardFilter(src); 
     filter = new LowerCaseFilter(filter); 
     filter = new StopFilter(filter, stopwords); 
     //I'm inclined to add it here, so the abbreviation "t.h.e." doesn't get whacked by the StopFilter. 
     filter = new WordDelimiterFilter(filter, WordDelimiterFilter.CATENATE_ALL, null); 
     return new TokenStreamComponents(src, filter); 
    } 
} 

Это не выглядит, как вы используете стандартный анализатор, но вы должны быть в состоянии понять, что (NGrams возможно?) в ваш анализ где-то.

+0

Спасибо @femtoRgon, анализатор, который вы предложили, находит 'e.x.a.m.' поиск' экзамена', и это здорово! Как я могу расширить его, чтобы найти также частичные слова, т. Е. Найти также «пример» для поиска «экзамена», не требуя использования подстановочных знаков? –

+0

Индексирование ngrams было бы хорошим способом сделать это. См. [NGramTokenFilter] (https://lucene.apache.org/core/5_5_0/analyzers-common/index.html?org/apache/lucene/analysis/ngram/NGramTokenFilter.html). – femtoRgon

Смежные вопросы