ElasticSearch多个AND/OR查询



我有一个像下面这样的模式-

{
"errorCode": "e015",
"errorDescription": "Description e015",
"storeId": "71102",
"businessFunction": "PriceFeedIntegration",
"createdDate": "2021-02-20T09:17:04.004",
"readBy": [
{
"userId": "scha3055"
},
{
"userId": "abcd1234"
}
]
}

我正在尝试搜索"errorCode","storeId","businessFunction"日期范围如下-

{
"query": {
"bool": {
"must": [
{
"terms": {
"errorCode": [
"e015",
"e020",
"e022"
]
}
},
{
"terms": {
"storeId": [
"71102",
"71103"
]
}
},

{
"range": {
"createdDate": {
"gte": "2021-02-16T09:17:04.000",
"lte": "2021-02-22T00:00:00.005"
}
}
}
]
}
}
}

但是当我添加另一个条件"businessFunction"查询无效

{
"query": {
"bool": {
"must": [
{
"terms": {
"errorCode": [
"e015",
"e020",
"e022"
]
}
},
{
"terms": {
"storeId": [
"71102",
"71103"
]
}
},
{
"terms": {
"errorDescription": [
"Description e020",
"71103"
]
}
},
{
"range": {
"createdDate": {
"gte": "2021-02-16T09:17:04.000",
"lte": "2021-02-22T00:00:00.005"
}
}
}
]
}
}
}

我在查询中缺少什么?当我加上第三项时条件时,查询不起作用。请建议或让我知道任何替代方法。

在您的示例中,您正在搜索"描述e020"但是在您的示例中,您存储了"Descriptione015"。

简短的回答,我希望这对你是正确的:

"描述e015"将被索引为两个术语["description","e015"]。

使用match_phrase而不是terms

...
{
"match_phrase": {
"errorDescription": "Description e015"
}
},
{
"range": {
"createdDate": {
"gte": "2021-02-16T09:17:04.000",
"lte": "2021-02-22T00:00:00.005"
}
}
}
....

在不知道你的映射的情况下,我认为你的errorDescription字段被分析了。

不推荐其他选项:如果您的字段被分析,并且您需要匹配精确的,在errorDescription.keyword

中搜索
{
"terms": {
"errorDescription.keyword": [
"Description e015"              
]
}
}

更新

长答:

正如我前面提到的,您的字段值被分析,然后从"PriceFeedIntegration2"pricefeedintegration2。

2选项
  • 按字段搜索。关键字又名businessFunction.keyword
  • 将您的字段映射更改为not analyzed。然后,您可以使用术语得到您所期望的结果。

选项:1

这是一个简单的方法,如果你从来没有在该字段上运行全文搜索,最好不要使用默认值。如果不重要,使用这个选项,它是最简单的。

检查您的businessFunction。关键字字段(如果不指定映射,默认创建)

上索引没有映射的数据my000001指数

curl -X "POST"  "http://localhost:9200/my000001/_doc" 
-H "Content-type: application/json" 
-d $'
{  
"errorCode": "e015",
"errorDescription": "Description e015",
"storeId": "71102",
"businessFunction": "PriceFeedIntegration",
"createdDate": "2021-02-20T09:17:04.004"

}'

检查

curl -X "GET" "localhost:9200/my000001/_analyze" 
-H "Content-type: application/json" 
-d $'{
"field": "businessFunction.keyword",
"text": "PriceFeedIntegration"
}'

结果:

{
"tokens": [
{
"token": "PriceFeedIntegration",
"start_offset": 0,
"end_offset": 20,
"type": "word",
"position": 0
}
]
}

使用businessFunction.keyword

获取结果
curl -X "GET" "localhost:9200/my000001/_search" 
-H "Content-type: application/json" 
-d $'{
"query": {
"bool": {

"must": [
{
"terms": {
"errorCode": [
"e015",
"e020",
"e022"
]
}
},
{
"terms": {
"storeId": [
"71102",
"71103"
]
}
},
{
"terms": {
"businessFunction.keyword": [
"PriceFeedIntegration2",
"PriceFeedIntegration"
]
}
},
{
"range": {
"createdDate": {
"gte": "2021-02-16T09:17:04.000",
"lte": "2021-02-22T00:00:00.005"
}
}
}
]
}
}
}' | jq

为什么不推荐作为默认选项?

"默认的动态字符串映射将索引字符串字段文本和关键字。如果您只需要其中一个,这是浪费。">

https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html

选项2

运行my000001指数

curl -X "GET" "localhost:9200/my000001/_analyze" 
-H "Content-type: application/json" 
-d $'{
"field": "businessFunction",
"text": "PriceFeedIntegration"
}'

您可以看到,您的字段值被分析了(根据分析器和提供的值进行了标记化、小写化和其他修改)结果:

{
"tokens": [
{
"token": "pricefeedintegration",
"start_offset": 0,
"end_offset": 20,
"type": "<ALPHANUM>",
"position": 0
}
]
}

这就是为什么你的搜索没有返回结果的原因。

"PriceFeedIntegration"与"pricefeedintegration"不匹配

"问题不在于术语查询;是数据的方式已被索引。">

您的businessFunction字段值已被分析。

如果您需要查找(搜索/过滤)的精确值,也许您需要更改您的"businessFunction"字段映射到not_analyzed.

更改映射需要删除索引并重新创建所需的映射。

如果您尝试更改现有索引的映射,您将得到一个"resource_already_exists_exception";错误。

下面是为了解决你的问题你需要知道的背景:https://www.elastic.co/guide/en/elasticsearch/guide/master/_finding_exact_values.html _finding_exact_values在新的my000005上创建映射指数

curl -X "PUT" "localhost:9200/my000005" 
-H "Content-type: application/json" 
-d $'{
"mappings" : {      
"properties" : {
"businessFunction" : {
"type" : "keyword"                    
},
"errorDescription" : {
"type" : "text"                    
},
"errorCode" : {
"type" : "keyword"                    
},
"createdDate" : {
"type" : "date"                    
},
"storeId": {
"type" : "keyword"                    
}
}
}
}'

索引数据
curl -X "POST"  "http://localhost:9200/my000005/_doc" 
-H "Content-type: application/json" 
-d $'
{  
"errorCode": "e015",
"errorDescription": "Description e015",
"storeId": "71102",
"businessFunction": "PriceFeedIntegration",
"createdDate": "2021-02-20T09:17:04.004"

}'

使用术语businessFunction获取预期的结果

curl -X "GET" "localhost:9200/my000005/_search" 
-H "Content-type: application/json" 
-d $'{
"query": {
"bool": {

"must": [
{
"terms": {
"errorCode": [
"e015",
"e020",
"e022"
]
}
},
{
"terms": {
"storeId": [
"71102",
"71103"
]
}
},
{
"terms": {
"businessFunction": [
"PriceFeedIntegration2",
"PriceFeedIntegration"
]
}
},
{
"range": {
"createdDate": {
"gte": "2021-02-16T09:17:04.000",
"lte": "2021-02-22T00:00:00.005"
}
}
}
]
}
}
}' | jq

这个答案是基于我认为是你的映射和你的需求。

在未来分享你的映射和你的ES版本,为了从社区得到更好的答案。

curl -X "GET" "localhost:9200/yourindex/_mappings"

请阅读https://www.elastic.co/guide/en/elasticsearch/guide/master/_finding_exact_values.html#_finding_exact_values这个https://www.elastic.co/blog/strings-are-dead-long-live-strings

最新更新