Поиск в спящем режиме: Elasticsearch и Lucene дают разные результаты поиска - PullRequest
1 голос
/ 20 января 2020

Я пытаюсь реализовать довольно базовую c функцию поиска для моего бэкэнда REST, используя Spring Data Rest и Hibernate Search. Я хотел бы позволить пользователям выполнять произвольные запросы, передавая строки запроса в функцию поиска. Чтобы облегчить локальный запуск серверной части и избежать запуска Elasticsearch для запуска тестов, я хотел бы иметь возможность работать с локальным индексом в этих ситуациях.

Моя проблема заключается в том, что следующий код не дает равных результатов с использованием локального индекса по сравнению с Elasticsearch. Я пытаюсь ограничить следующий код тем, что, на мой взгляд, имеет значение.

Сущность:

@Indexed(index = "MyEntity")
@AnalyzerDef(name = "ngram",
    tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
    filters = {
      @TokenFilterDef(factory = StandardFilterFactory.class),
      @TokenFilterDef(factory = LowerCaseFilterFactory.class),
      @TokenFilterDef(factory = StopFilterFactory.class),
      @TokenFilterDef(factory = NGramFilterFactory.class,
        params = {
          @Parameter(name = "minGramSize", value = "2"),
          @Parameter(name = "maxGramSize", value = "3") } )
    }
)
public class MyEntity {

    @NotNull
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES, analyzer = @Analyzer(definition = "ngram"))
    private String name;

    @Field(analyze = Analyze.YES, store = Store.YES)
    @FieldBridge(impl = StringCollectionFieldBridge.class)
    @ElementCollection(fetch = FetchType.EAGER)
    private Set<String> tags = new HashSet<>();

}

application.yml для локального индекса:

spring: 
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: false

application .yml для Elasticsearch:

spring: 
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        search:
          default:
            indexmanager: elasticsearch
            elasticsearch:
              host: 127.0.0.1:9200
              required_index_status: yellow

Конечная точка поиска:

private static String[] FIELDS = { "name", "tags" };

@Override
public List<MyEntity> querySearch(String queryString) throws ParseException {
    QueryParser queryParser = new MultiFieldQueryParser(FIELDS, new SimpleAnalyzer());
    queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);
    org.apache.lucene.search.Query query = queryParser.parse(queryString);

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

    javax.persistence.Query persistenceQuery = 
            fullTextEntityManager.createFullTextQuery(query, MyEntity.class);

    return persistenceQuery.getResultList();
}

Я создаю экземпляр MyEntity со следующими значениями:

$ curl 'localhost:8086/myentities'
{
  "_embedded" : {
    "myentities" : [ {
      "name" : "Test Entity",
      "tags" : [ "bar", "foobar", "foo" ],
      "_links" : {
        ...
      }
    } ]
  },
  "_links" : {
    ...
  }
}

Работают следующие запросы (вернуть эту сущность), используя Elasticsearch:

  • name: Test
  • name: Entity
  • tags: bar

Использование локального index, я получаю результат для "tags: bar: но запросы в поле имени не возвращают результатов. Есть идеи, почему это так?

1 Ответ

0 голосов
/ 20 января 2020

Вы должны убедиться, что отображение Elasticsearch правильно создано Hibernate Search. По умолчанию Hiberante Search создает отображение, только если оно отсутствует.

Если вы запустили свое приложение один раз, затем изменили отображение и снова запустили приложение, возможно, поле name не иметь правильное значение в Elasticsearch.

В режиме разработки попробуйте следующее:

spring: 
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        search:
          default:
            indexmanager: elasticsearch
            elasticsearch:
              host: 127.0.0.1:9200
              required_index_status: yellow
              index_schema_management_strategy: drop-and-create-and-drop

См. https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#elasticsearch -schema-management-стратегии

Обратите внимание, что документы, успешно проиндексированные, к сожалению, не указывают на правильность вашего отображения: Elasticsearch даже создает поля динамически, когда вы пытаетесь проиндексировать неизвестные поля, пытаясь угадать их тип (как правило, неправильно в случае текстовых полей ...). Вы можете использовать стратегию управления индексами validate, чтобы быть уверенным, что в bootstrap отображение Elasticsearch синхронизировано c с Hibernate Search.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...