0

I faced a problem connected with Elasticsearch while implementing full text search. When I try to find documents in index I face this problem

2025-08-27T09:15:59.544+03:00 ERROR 19622 --- [Muse] [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.data.elasticsearch.UncategorizedElasticsearchException: [es/search] failed: [search_phase_execution_exception] all shards failed] with root cause

co.elastic.clients.elasticsearch._types.ElasticsearchException: [es/search] failed: [search_phase_execution_exception] all shards failed

This is the dependency tree:

andrejburlacko@MacBook-Air-Andrej team28 % mvn dependency:tree | grep elasticsearch
[INFO] +- org.springframework.boot:spring-boot-starter-data-elasticsearch:jar:3.5.4:compile
[INFO] |  \- org.springframework.data:spring-data-elasticsearch:jar:5.5.2:compile
[INFO] |     +- co.elastic.clients:elasticsearch-java:jar:8.18.1:compile
[INFO] |     +- org.elasticsearch.client:elasticsearch-rest-client:jar:8.18.1:compile

This is how I run elastic in docker:

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 \
  -e "discovery.type=single-node" \
  -e "xpack.security.enabled=false" \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  elasticsearch:8.18.1

This how my indexes look like:

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size dataset.size

yellow open questions _nkW3NzETNanGDBXuhiQyQ 1 1 50 0 23.7kb 23.7kb 23.7kb

yellow open tags BdaRQbRWTzSGQIWxod96VQ 1 1 0 0 249b 249b 249b

This is how mapping structure looks like for question:

{
  "questions" : {
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "id" : {
          "type" : "keyword"
        },
        "questionText" : {
          "type" : "text"
        },
        "score" : {
          "type" : "integer"
        },
        "title" : {
          "type" : "text"
        },
        "viewsCount" : {
          "type" : "integer"
        }
      }
    }
  }
}

When I try search by hands through elastic api, I get my questions successfully

GET http://localhost:9200/questions/_search?q=title:производительность&pretty

{
    "took": 59,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 2.920971,
        "hits": [
            {
                "_index": "questions",
                "_id": "b23e4dcc-cc13-4ba3-a354-9aee75238375",
                "_score": 2.920971,
                "_source": {
                    "_class": "ru.t1.usernamedrew.muse.entity.elastic.SearchQuestion",
                    "id": "b23e4dcc-cc13-4ba3-a354-9aee75238375",
                    "title": "SQL индексы производительность",
                    "questionText": "Как индексы влияют на производительность SQL запросов?",
                    "viewsCount": 126,
                    "score": 12
                }
            },
            {
                "_index": "questions",
                "_id": "d54852a3-b6bd-4e99-8376-faa19cfe9a45",
                "_score": 2.5565581,
                "_source": {
                    "_class": "ru.t1.usernamedrew.muse.entity.elastic.SearchQuestion",
                    "id": "d54852a3-b6bd-4e99-8376-faa19cfe9a45",
                    "title": "Java Stream API производительность",
                    "questionText": "Влияет ли использование Stream API на производительность Java приложений?",
                    "viewsCount": 95,
                    "score": 9
                }
            }
        ]
    }
}

This is how my search service looks like:

@Service
@RequiredArgsConstructor
public class SearchServiceImpl implements SearchService {
    private final SearchQuestionRepository searchQuestionRepository;
    private final SearchTagRepository searchTagRepository;
    private final QuestionService questionService;
    private final TagService tagService;
    private final ElasticsearchOperations elasticsearchOperations;

    // Поиск вопросов по заголовку
    @Override
    public Slice<QuestionPreviewDTO> searchQuestions(String query, Pageable pageable) {
        List<UUID> questionIds = searchQuestionRepository.findByTitleContainingIgnoreCase(query, pageable) // <- it falls then findByTitleIgnoreCase try’s to make a query
                .getContent().stream()
                .map(SearchQuestion::getId)
                .toList();

        return questionService.getQuestionsByIds(questionIds, pageable);
    }

    // Поиск тегов по заголовку
    @Override
    public Slice<TagDTO> searchTags(String query, Pageable pageable) {
        List<UUID> tagsIds = searchTagRepository.findByTitleContaining(query, pageable)
                .getContent().stream()
                .map(SearchTag::getId)
                .toList();

        return tagService.findAllByIds(tagsIds, pageable);
    }

    // Индексация вопроса
    @Override
    public void indexQuestion(QuestionPreviewDTO question) {
        searchQuestionRepository.save(convertToSearchQuestion(question));
    }

    @Override
    public void indexTags(Tag tags) {
        // TODO
    }

    @Override
    @Transactional
    public void reindexAllQuestions() {
        searchQuestionRepository.deleteAll();

        int batchSize = 100;
        int offset = 0;

        while (true) {
            Pageable pageable = PageRequest.of(offset, batchSize);
            Slice<QuestionPreviewDTO> questionSlice = questionService.getQuestions(pageable);

            if (questionSlice.getContent().isEmpty()) {
                break;
            }

            List<SearchQuestion> searchQuestions = questionSlice.getContent().stream()
                    .map(this::convertToSearchQuestion)
                    .toList();

            searchQuestionRepository.saveAll(searchQuestions);

            offset++;
        }
    }

    private SearchQuestion convertToSearchQuestion(QuestionPreviewDTO question) {
        return SearchQuestion.builder()
                .id(question.getId())
                .title(question.getTitle())
                .questionText(question.getQuestionText())
                .viewsCount(question.getViewsCount())
                .score(question.getScore())
                .build();
    }
}

My documents:

@Document(indexName = "questions")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SearchQuestion {
    @Id
    @Field(type = FieldType.Keyword)
    private UUID id;

    @Field(type = FieldType.Text)
    private String title;

    @Field(type = FieldType.Text)
    private String questionText;

    @Field(type = FieldType.Integer)
    private Integer viewsCount;

    @Field(type = FieldType.Integer)
    private Integer score;
}

@Document(indexName = "tags")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SearchTag {
    @Id
    @Field(type = FieldType.Keyword)
    private UUID id;

    @Field(type = FieldType.Text)
    private String title;

    @Field(type = FieldType.Text)
    private String description;
}

And elastic search repositories:

public interface SearchQuestionRepository extends ElasticsearchRepository<SearchQuestion, UUID> {
    Slice<SearchQuestion> findByTitleContainingIgnoreCase(String title, Pageable pageable);
}

public interface SearchTagRepository extends ElasticsearchRepository<SearchTag, UUID> {
    Slice<SearchTag> findByTitleContaining(String title, Pageable pageable);
}

Controller:

@RestController
@RequestMapping("/api/search")
@RequiredArgsConstructor
@Tag(name = "Контроллер поиска", description = "Поиск вопросов по названию и тегам")
public class SearchController {
    private final SearchService searchService;

    @GetMapping("/questions")
    @Operation(summary = "Поиск вопросов по заголовку с использованием ElasticSearch")
    public ResponseEntity<Slice<QuestionPreviewDTO>> searchQuestions(
            @RequestParam("q") String prefix,
            @PageableDefault(size = 20, sort = "createdAt") Pageable pageable) {
        return ResponseEntity.ok(searchService.searchQuestions(prefix, pageable)); // falls in search service, reindex works well
    }

    @GetMapping("/tags")
    @Operation(summary = "Поиск тега по названию с использованием ElasticSearch")
    public ResponseEntity<Slice<TagDTO>> searchTags(
            @RequestParam("q") String prefix,
            @PageableDefault(size = 20) Pageable pageable) {
        return ResponseEntity.ok(searchService.searchTags(prefix, pageable));
    }

    @GetMapping("/reindex")
    @Operation(summary = "Реиндексация вопросов в ElasticSearch")
    public void reindex() {
        searchService.reindexAllQuestions();
    }
}

Full text of exception:

co.elastic.clients.elasticsearch._types.ElasticsearchException: [es/search] failed: [search_phase_execution_exception] all shards failed
    at co.elastic.clients.transport.ElasticsearchTransportBase.getApiResponse(ElasticsearchTransportBase.java:357) ~[elasticsearch-java-8.18.1.jar:na]
    at co.elastic.clients.transport.ElasticsearchTransportBase.performRequest(ElasticsearchTransportBase.java:141) ~[elasticsearch-java-8.18.1.jar:na]
    at co.elastic.clients.elasticsearch.ElasticsearchClient.search(ElasticsearchClient.java:5374) ~[elasticsearch-java-8.18.1.jar:na]
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate.lambda$doSearch$14(ElasticsearchTemplate.java:356) ~[spring-data-elasticsearch-5.5.2.jar:5.5.2]
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate.execute(ElasticsearchTemplate.java:689) ~[spring-data-elasticsearch-5.5.2.jar:5.5.2]
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate.doSearch(ElasticsearchTemplate.java:356) ~[spring-data-elasticsearch-5.5.2.jar:5.5.2]
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate.search(ElasticsearchTemplate.java:349) ~[spring-data-elasticsearch-5.5.2.jar:5.5.2]
    at org.springframework.data.elasticsearch.core.SearchOperations.searchOne(SearchOperations.java:91) ~[spring-data-elasticsearch-5.5.2.jar:5.5.2]
    at org.springframework.data.elasticsearch.repository.query.AbstractElasticsearchRepositoryQuery.execute(AbstractElasticsearchRepositoryQuery.java:130) ~[spring-data-elasticsearch-5.5.2.jar:5.5.2]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[spring-data-commons-3.5.2.jar:3.5.2]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[spring-data-commons-3.5.2.jar:3.5.2]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:170) ~[spring-data-commons-3.5.2.jar:3.5.2]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:149) ~[spring-data-commons-3.5.2.jar:3.5.2]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.9.jar:6.2.9]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.9.jar:6.2.9]
    at jdk.proxy2/jdk.proxy2.$Proxy180.findByTitleContainingIgnoreCase(Unknown Source) ~[na:na]
    at ru.t1.usernamedrew.muse.service.impl.SearchServiceImpl.searchQuestions(SearchServiceImpl.java:40) ~[classes/:na] **<-- it falls when it try's to make a query in SearchQuestionRepository**
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360) ~[spring-aop-6.2.9.jar:6.2.9]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:724) ~[spring-aop-6.2.9.jar:6.2.9]
    at ru.t1.usernamedrew.muse.service.impl.SearchServiceImpl$$SpringCGLIB$$0.searchQuestions(<generated>) ~[classes/:na]
    at ru.t1.usernamedrew.muse.controller.SearchController.searchQuestions(SearchController.java:30) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:991) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:896) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.43.jar:6.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.43.jar:6.0]

I've tried different types of queries. Tried to use NativeQuery, repositories with Page and List return types. Tried to set number_of_replicas to 0. What can I do next to fix this problem, also I tried to configure elastic with java code. All my shards are green and yellow. May be I wrote something wrong in elastic's repositories but I can't identify what's the problem. Spring Data Elastic documentation says it should work with Page and Slice.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.