2015-01-06 1 views
0

Прежде всего, с Новым годом!Hibernate Искать несколько полей с @ClassBridge

Я хочу индексировать метку объекта на нескольких языках.

У меня есть 2 сущности:

MyEntity

  • labelCode

Перевод

  • код
  • LanguageCode
  • label

MyEntity.labelCode должен совпадать с Translation.code, тогда у меня есть несколько ярлыков для нескольких языков на экземпляр MyEntity.

Я написал ClassBridge на MyEntity добавить несколько полей для документа:

class I18NTranslationClassBridge implements FieldBridge { 

Analyzer analyzer 

@Override 
void set(String name, Object value, Document document, LuceneOptions luceneOptions) { 
    if (value && value instanceof I18NDictionaryCategory) { 
     I18NDictionaryCategory entity = value as I18NDictionaryCategory 

     String labelCode = entity.getLabelCode() 
     def translations = TranslationData.findAllByCode(labelCode) 
     if (!analyzer) analyzer = Search.getFullTextSession(Holders.getApplicationContext().sessionFactory.currentSession).getSearchFactory().getAnalyzer('wildcardAnalyzer') 
     translations?.each { translation -> 
      document.add(getStringField("labelCode_${translation.languageCode}", translation.label, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO, 1f, analyzer)) 
      document.add(getStringField("labelCode__${translation.languageCode}_full", translation.label, Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO, 1f, null)) 
     } 

    } 
} 

private static Field getStringField(String fieldName, String fieldValue, Field.Store store, Field.Index index, Field.TermVector termVector, float boost, Analyzer analyzer) { 
    Field field = new Field(fieldName, fieldValue, store, index, termVector); 
    field.setBoost(boost); 
    // manually apply token stream from analyzer, as hibernate search does not 
    // apply the specified analyzer properly 
    if (analyzer) { 
     try { 
      field.setTokenStream(analyzer.reusableTokenStream(fieldName, new StringReader(fieldValue))); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    return field 
} 

}

Я хотел бы, чтобы индекс 2 поля для каждого языка: 1 без анализатора и не Tokenizer (для сортировки результаты), а другой - с токенизатором (для полнотекстового поиска).

Моя проблема в том, что все поля без анализатора хорошо проиндексированы, но поля с анализатором не являются. Только 1 язык правильно проиндексирован.

Я стараюсь делать это с ClassBridge или FieldBridge без успеха.

Любое предложение?

С наилучшими пожеланиями,

Léo

ответ

1

Вы не должны использовать анализатор в пределах класса/поля моста. Анализаторы применяются на более позднем этапе. Hibernate Search собирает все необходимые анализаторы в так называемом ScopedAnalyzer, который используется, когда Lucene Document добавляется в индекс. Для поддержки вашего варианта использования вы можете использовать функцию выбора динамического анализатора. См. Также http://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#d0e4119.

Основным подходом является определение анализаторов, специфичных для языка, посредством @AnalyzerDiscriminator. Это делает их доступными по всему миру по имени. Затем вам нужно реализовать org.hibernate.search.analyzer.Decriminator. Вы в основном возвращаете правильное имя анализатора в зависимости от вашего имени поля (при условии, что имена полей содержат в некотором роде код языка). Наконец, но не в последнюю очередь вам необходимо аннотировать MyEntity с @AnalyzerDiscriminator(impl = MyDiscriminator.class).

+0

Спасибо! Документ теперь правильно проиндексирован. – persa