【问题标题】:Java Spring elasticsearch "Failed to derive xcontent" with @QueryJava Spring elasticsearch“无法派生xcontent”与@Query
【发布时间】:2021-05-05 02:40:10
【问题描述】:

我在我的一个 elasticsearch 存储库中有一个自定义 @Query,因为 autoGenerated 方法没有使用 match(而不是 query_string 和 analyze_wildcard),因此例如不能使用空格。这个查询对我来说看起来很简单,所以我认为自己编写不会有问题。

@Query("\"bool\": { " +
        "   \"filter\": [ " +
        "    {  " +
        "       \"term\": { " +
        "          \"userId.keyword\": \"?0\" " +
        "        } " +
        "    }, " +
        "    {" +
        "       \"match\": { " +
        "          \"content\": \"?1\" " +
        "       }" +
        "     } " +
        "   ] " +
        "  }")
Page<SearchablePageHistory> findAllByUserIdAndContentLike(String userId, String content, Pageable pageable);

但是当我尝试执行该函数时,我收到以下错误:

org.elasticsearch.ElasticsearchStatusException: Elasticsearch exception [type=x_content_parse_exception, reason=Failed to derive xcontent]
    at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177) ~[elasticsearch-7.6.2.jar:7.6.2]
    at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1793) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
    at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1770) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
    at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1527) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
    at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1484) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
    at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1454) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
    at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:970) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
    at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.lambda$search$10(ElasticsearchRestTemplate.java:265) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.execute(ElasticsearchRestTemplate.java:351) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.search(ElasticsearchRestTemplate.java:265) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.data.elasticsearch.repository.query.ElasticsearchStringQuery.execute(ElasticsearchStringQuery.java:89) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195) ~[spring-data-commons-2.3.0.RELEASE.jar:2.3.0.RELEASE]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152) ~[spring-data-commons-2.3.0.RELEASE.jar:2.3.0.RELEASE]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.0.RELEASE.jar:2.3.0.RELEASE]
    Suppressed: org.elasticsearch.client.ResponseException: method [POST], host [http://localhost:9200], URI [/history/_search?pre_filter_shard_size=128&typed_keys=true&max_concurrent_shard_requests=5&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=dfs_query_then_fetch&batched_reduce_size=512&ccs_minimize_roundtrips=true], status line [HTTP/1.1 400 Bad Request]
{"error":{"root_cause":[{"type":"x_content_parse_exception","reason":"Failed to derive xcontent"}],"type":"x_content_parse_exception","reason":"Failed to derive xcontent"},"status":400}
        at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:283) ~[elasticsearch-rest-client-7.6.2.jar:7.6.2]
        at org.elasticsearch.client.RestClient.performRequest(RestClient.java:261) ~[elasticsearch-rest-client-7.6.2.jar:7.6.2]
        at org.elasticsearch.client.RestClient.performRequest(RestClient.java:235) ~[elasticsearch-rest-client-7.6.2.jar:7.6.2]
        at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1514) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2]
        ... 124 common frames omitted

通过调试,我在 org.elasticsearch.client.RestClient.java:244 中跟踪了发送到 elasticsearch 的原始 Rest-Request,发现这是发送到服务器的有效负载:

{"from":0,"size":10,"query":{"wrapper":{"query":"ImJvb2wiOiB7ICAgICJmaWx0ZXIiOiBbICAgICB7ICAgICAgICJ0ZXJtIjogeyAgICAgICAidXNlcklkLmtleXdvcmQiOiAiMzFjMjA5NTktNjg5Zi00YjI4LWExNzctNmQ3ZTQ2YTBhYzMwIiAgICAgIH0gICAgIH0sICAgeyJtYXRjaCI6IHsgICAgImNvbnRlbnQiOiAidGVzdHNzIiAgIH19ICAgIF0gICB9"}},"version":true,"sort":[{"id":{"order":"desc"}}]}

使用该有效负载,错误并不令人惊讶,但是我不知道为什么会有这种奇怪的字符喃喃自语。我怀疑这应该是我未正确使用的自定义查询。我通过调试到这一行得到了这个有效载荷:

httpResponse = client.execute(context.requestProducer, context.asyncResponseConsumer, context.context, null).get();

然后执行:

StandardCharsets.UTF_8.decode(((NByteArrayEntity) ((HttpPost) ((HttpAsyncMethods.RequestProducerImpl) context.requestProducer).request).entity).buf).toString()

这些是我在 Repository-Class 中使用的导入和类名:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.stream.Stream;

public interface SearchablePageHistoryRepository extends ElasticsearchRepository<SearchablePageHistory, Integer> {
    Page<SearchablePageHistory> findAllByUserId(String userId, Pageable pageable);

    @Query("\"bool\": { " +
        "   \"filter\": [ " +
        "    {  " +
        "       \"term\": { " +
        "          \"userId.keyword\": \"?0\" " +
        "        } " +
        "    }, " +
        "    {" +
        "       \"match\": { " +
        "          \"content\": \"?1\" " +
        "       }" +
        "     } " +
        "   ] " +
        "  }")
    Page<SearchablePageHistory> findAllByUserIdAndContentLike(String userId, String content, Pageable pageable);
}

我不使用@Query 的所有其他查询都可以正常工作。我不知道我做错了什么,因为我的示例与文档中给出的示例非常相似:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.query-methods.at-query

【问题讨论】:

    标签: java spring elasticsearch jpa spring-data-elasticsearch


    【解决方案1】:

    Hard facepalm,我发现了我的错误 -> 仍然会留下这篇文章,以防其他人偶然发现同样的问题,因为我认为错误消息不是很有帮助。

    我只是忘记了查询外部的括号:

    改变这个:

    @Query("\"bool\": { " +
            "   \"filter\": [ " +
            "    {  " +
            "       \"term\": { " +
            "          \"userId.keyword\": \"?0\" " +
            "        } " +
            "    }, " +
            "    {" +
            "       \"match\": { " +
            "          \"content\": \"?1\" " +
            "       }" +
            "     } " +
            "   ] " +
            "  }")
        Page<SearchablePageHistory> findAllByUserIdAndContentLike(String userId, String content, Pageable pageable);
    

    到这里:

        @Query("{\"bool\": { " +
            "   \"filter\": [ " +
            "    {  " +
            "       \"term\": { " +
            "          \"userId.keyword\": \"?0\" " +
            "        } " +
            "    }, " +
            "    {" +
            "       \"match\": { " +
            "          \"content\": \"?1\" " +
            "       }" +
            "     } " +
            "   ] " +
            "  }}")
    Page<SearchablePageHistory> findAllByUserIdAndContentLike(String userId, String content, Pageable pageable);
    

    解决了问题。

    加法:

    "ImJvb2wiOiB7ICAgICJmaWx0ZXIiOiBbICAgICB7ICAgICAgICJ0ZXJtIjogeyAgICAgICAidXNlcklkLmtleXdvcmQiOiAiMzFjMjA5NTktNjg5Zi00YjI4LWExNzctNmQ3ZTQ2YTBhYzMwIiAgICAgIH0gICAgIH0sICAgeyJtYXRjaCI6IHsgICAgImNvbnRlbnQiOiAidGVzdHNzIiAgIH19ICAgIF0gICB9" 
    

    是一个包装查询,它是一个base64编码的字符串,包含

    ""bool": {    "filter": [     {       "term": {       "userId.keyword": "31c20959-689f-4b28-a177-6d7e46a0ac30"      }     },   {"match": {    "content": "testss"   }}    ]   }"
    

    【讨论】:

      【解决方案2】:

      有类似的问题,实际上是没有括号

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多