"UncategorizedElasticsearchException": [es/search] failed: [x_content_parse_exception] [1:98] [bool] failed to parse field [should]

huangapple go评论58阅读模式
英文:

"UncategorizedElasticsearchException": [es/search] failed: [x_content_parse_exception] [1:98] [bool] failed to parse field [should]

问题

以下是您提供的内容的翻译:

使用的版本:

Spring Data Elasticsearch = 5.0.4

Elasticsearch = 8.5.3

Spring Boot = 3.0.5

产品索引:

@AllArgsConstructor
@Data
@Document(indexName = "product", versionType = Document.VersionType.INTERNAL)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Product {

    @Id
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String id;
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String brand;
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String name;
    @NotNull
    @PositiveOrZero
    @Field(type = FieldType.Float)
    private Float price;
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String category;
    @Field(type = FieldType.Keyword, name = "image_url")
    private String imageURL;
    @NotNull
    @PositiveOrZero
    @Field(type = FieldType.Long)
    private Long stock;
    @NotNull
    @Field(type = FieldType.Text, analyzer = "english")
    private String description;
}

产品仓库:

public interface ProductRepository extends ElasticsearchRepository<Product, String> {

    @Query("{\"bool\":{\"should\":[{\"wildcard\":{\"name\":\"*?0*\"}},{\"term\":{\"category\":\"?1\"}},{\"terms\":{\"brand\": ?2}},{\"range\":{\"price\":{\"gte\":?3,\"lte\":?4}}}]}}")
    Page<Product> productSearch(String name, String category, List<String> brands,
                                Integer priceMin, Integer priceMax, Pageable pageable);
}

产品映射:

{
  "product": {
    "mappings": {
      "properties": {
        "_class": {
          "type": "keyword",
          "index": false,
          "doc_values": false
        },
        "brand": {
          "type": "keyword"
        },
        "category": {
          "type": "keyword"
        },
        "description": {
          "type": "text",
          "analyzer": "english"
        },
        "id": {
          "type": "keyword"
        },
        "image_url": {
          "type": "keyword"
        },
        "name": {
          "type": "keyword"
        },
        "price": {
          "type": "float"
        },
        "stock": {
          "type": "long"
        }
      }
    }
  }
}

我是Elasticsearch的新手,通过创建一个小型电子商务网站来学习它。我在实现上述搜索查询时遇到问题。当我在Kibana控制台中执行查询时,它能够正常工作。需要注意的一点是,我确实传递了品牌、名称和类别的null值,但我相信我在某处读到过如果它们为空,则会被忽略?但不确定。这可能是问题所在。希望有人能帮助我,谢谢。

编辑:我已经发现问题出在搜索查询的品牌术语部分。我希望搜索在品牌字段为空时忽略它。我该如何做到这一点?

英文:

versions used:

Spring Data Elasticsearch = 5.0.4

Elasticsearch = 8.5.3

Spring Boot = 3.0.5

Product index:

@AllArgsConstructor
@Data
@Document(indexName = &quot;product&quot;, versionType = Document.VersionType.INTERNAL)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Product {

    @Id
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String id;
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String brand;
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String name;
    @NotNull
    @PositiveOrZero
    @Field(type = FieldType.Float)
    private Float price;
    @NotEmpty
    @Field(type = FieldType.Keyword)
    private String category;
    @Field(type = FieldType.Keyword, name = &quot;image_url&quot;)
    private String imageURL;
    @NotNull
    @PositiveOrZero
    @Field(type = FieldType.Long)
    private Long stock;
    @NotNull
    @Field(type = FieldType.Text, analyzer = &quot;english&quot;)
    private String description;
}

Products repository:

public interface ProductRepository extends ElasticsearchRepository&lt;Product, String&gt; {


    @Query(&quot;{\&quot;bool\&quot;:{\&quot;should\&quot;:[{\&quot;wildcard\&quot;:{\&quot;name\&quot;:\&quot;*?0*\&quot;}},{\&quot;term\&quot;:{\&quot;category\&quot;:\&quot;?1\&quot;}},{\&quot;terms\&quot;:{\&quot;brand\&quot;: ?2}},{\&quot;range\&quot;:{\&quot;price\&quot;:{\&quot;gte\&quot;:?3,\&quot;lte\&quot;:?4}}}]}}&quot;)
    Page&lt;Product&gt; productSearch(String name, String category, List&lt;String&gt; brands,
                                Integer priceMin, Integer priceMax, Pageable pageable);
   


}

Products mapping:

{
  &quot;product&quot;: {
    &quot;mappings&quot;: {
      &quot;properties&quot;: {
        &quot;_class&quot;: {
          &quot;type&quot;: &quot;keyword&quot;,
          &quot;index&quot;: false,
          &quot;doc_values&quot;: false
        },
        &quot;brand&quot;: {
          &quot;type&quot;: &quot;keyword&quot;
        },
        &quot;category&quot;: {
          &quot;type&quot;: &quot;keyword&quot;
        },
        &quot;description&quot;: {
          &quot;type&quot;: &quot;text&quot;,
          &quot;analyzer&quot;: &quot;english&quot;
        },
        &quot;id&quot;: {
          &quot;type&quot;: &quot;keyword&quot;
        },
        &quot;image_url&quot;: {
          &quot;type&quot;: &quot;keyword&quot;
        },
        &quot;name&quot;: {
          &quot;type&quot;: &quot;keyword&quot;
        },
        &quot;price&quot;: {
          &quot;type&quot;: &quot;float&quot;
        },
        &quot;stock&quot;: {
          &quot;type&quot;: &quot;long&quot;
        }
      }
    }
  }
}

I'm new to Elasticsearch and I'm learning it by making a small ecommerce website. I am having a problem implementing the above search query. The query works when I execute it trough Kibana console. One thing to note is that I do pass null values of brands, name and category, but I believe I read somewhere that it then ignores those values? Not absolutely sure. that could be the problem. I hope someone can help me thanks.

EDIT: I've figured out that the problem is with the brands terms part of the search query. I want the search to ignore the brands field if it's empty. how do I do that?

答案1

得分: 1

你可以对查询进行一些更改,以充分利用缓存以获得最大性能。将“should”子句中的过滤条件放入“filter”子句中。如果品牌列表为空,您可以创建另一种方法,在没有品牌列表的情况下运行productSearch方法。在这种情况下,您将有两个查询,一个包含列表,一个不包含。

我建议的查询如下:

{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "category": "?1"
          }
        },
        {
          "terms": {
            "brand": [
              "VALUE1",
              "VALUE2"
            ]
          }
        },
        {
          "range": {
            "price": {
              "gte": "?3",
              "lte": "?4"
            }
          }
        }
      ],
      "must": [
        {
          "wildcard": {
            "name": "*?0*"
          }
        }
      ]
    }
  }
}
英文:

You can add some changes for you to take advantage of the maximum performance as a cache in your query.
The filters that you have in the "should" clause you can put in the "filter" clause.
If you have an empty Brand list you can have another method that runs the productSearch method without the Brand list. In this case you would have two queries, one with the list and one without.

The query I suggest would be this:

{
  &quot;query&quot;: {
    &quot;bool&quot;: {
      &quot;filter&quot;: [
        {
          &quot;term&quot;: {
            &quot;category&quot;: &quot;?1&quot;
          }
        },
        {
          &quot;terms&quot;: {
            &quot;brand&quot;: [
              &quot;VALUE1&quot;,
              &quot;VALUE2&quot;
            ]
          }
        },
        {
          &quot;range&quot;: {
            &quot;price&quot;: {
              &quot;gte&quot;: &quot;?3&quot;,
              &quot;lte&quot;: &quot;?4&quot;
            }
          }
        }
      ],
      &quot;must&quot;: [
        {
          &quot;wildcard&quot;: {
            &quot;name&quot;: &quot;*?0*&quot;
          }
        }
      ]
    }
  }
}

huangapple
  • 本文由 发表于 2023年5月8日 01:55:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定