Я пытаюсь реализовать довольно базовую 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: но запросы в поле имени не возвращают результатов. Есть идеи, почему это так?