Я пытаюсь создать класс, который будет автоматически записывать в ElasticSearch через клиент высокого уровня Rest с операциями (create, createBatch, remove, removeBatch, update, updateBatch), и все эти операции будут работать, и все мои тесты будут успешными , Чтобы добавить немного большей гибкости, я хотел реализовать следующий метод: (find, findAll, getFirsts (n), getLasts (n)). find (key) и findAll () работают отлично, но getFirsts (n) и getLasts (n) не работают совсем.
Вот контекст: перед каждым тестом -> тест «Убедитесь, что индекс» "существует и создайте его, если его нет. После каждого контрольного примера -> Удалить индекс" test "Для getFirsts (n) и getLasts (n) я вызываю create, чтобы иметь несколько элементов в ElasticSearch, а затем выполняю поиск в соответствии с uniqueKey.
Вот отображение моего тестового объекта:
{
"properties": {
"date": { "type": "long" },
"name": { "type": "text" },
"age": { "type": "integer" },
"uniqueKey": { "type": "keyword" }
}
}
Вот мой тестовый пример:
@Test
public void testGetFirstByIds() throws BeanPersistenceException {
List<StringTestDataBean> beans = new ArrayList<>();
StringTestDataBean bean1 = new StringTestDataBean();
bean1.setName("Tester");
bean1.setAge(22);
bean1.setTimeStamp(23213987321712L);
beans.add(elasticSearchService.create(bean1));
StringTestDataBean bean2 = new StringTestDataBean();
bean1.setName("Antonio");
bean1.setAge(27);
bean1.setTimeStamp(2332321117321712L);
beans.add(elasticSearchService.create(bean2));
Assert.assertNotNull("The beans created should not be null", beans);
Assert.assertEquals("The uniqueKeys of the fetched list should match the existing",
beans.stream()
.map(ElasticSearchBean::getUniqueKey)
.sorted((b1,b2) -> Long.compare(Long.parseLong(b2),Long.parseLong(b1)))
.collect(Collectors.toList()),
elasticSearchService.getFirstByIds(2).stream()
.map(ElasticSearchBean::getUniqueKey)
.collect(Collectors.toList())
);
}
Вот getFirstByIds (n):
@Override
public Collection<B> getFirstByIds(int entityCount) throws BeanPersistenceException {
assertBinding();
FilterContext filterContext = new FilterContext();
filterContext.setLimit(entityCount);
filterContext.setSort(Collections.singletonList(new FieldSort("uniqueKey",true)));
return Optional.ofNullable(find(filterContext)).orElseThrow();
}
Вот находка (filterContext):
@Override
public List<B> find(FilterContext filter) throws BeanPersistenceException {
assertBinding();
BoolQueryBuilder query = QueryBuilders.boolQuery();
List<FieldFilter> fields = filter.getFields();
StreamUtil.ofNullable(fields)
.forEach(fieldFilter -> executeFindSwitchCase(fieldFilter,query));
SearchSourceBuilder builder = new SearchSourceBuilder().query(query);
builder.from((int) filter.getFrom());
builder.size(((int) filter.getLimit() == -1) ? FILTER_LIMIT : (int) filter.getLimit());
SearchRequest request = new SearchRequest();
request.indices(index);
request.source(builder);
List<FieldSort> sorts = filter.getSort();
StreamUtil.ofNullable(sorts)
.forEach(fieldSort -> builder.sort(SortBuilders.fieldSort(fieldSort.getField()).order(
fieldSort.isAscending() ? SortOrder.ASC : SortOrder.DESC)));
try {
if (strict)
client.indices().refresh(new RefreshRequest(index), RequestOptions.DEFAULT);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
List<B> results = new ArrayList<>();
for (SearchHit hit : hits)
results.add(objectMapper.readValue(hit.getSourceAsString(), clazz));
return results;
}
catch(IOException e){
logger.error(e.getMessage(),e);
}
return null;
}
Проблема возникает, если я запускаю тестовый набор более одного раза. В первый раз тест проходит нормально, но когда мы доходим до второго теста, я получаю исключение:
ElasticsearchStatusException[Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]
]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Fielddata is disabled on text fields by default. Set fielddata=true on [name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.]];
После осмотра в течение дня я понял, что карта изменилась с оригинала отображение (карта указана в начале), и оно автоматически создается следующим образом:
"test": {
"aliases": {},
"mappings": {
"properties": {
"age": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"timeStamp": {
"type": "long"
},
"uniqueKey": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
Как я вижу, отображение меняется автоматически и выдает ошибку. Спасибо за любую помощь!