ElasticSearch:如何筛选和将具有数组字段的索引更改为布尔字段?

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

ElasticSearch : how to filter and change an index with an array field to a boolean field?

问题

以下是翻译好的内容:

1st Example:

我正在使用 ElasticSearch 8.6

以下是我的索引:

_source" : {
    "fieldA" : "M",
    "fieldB" : "SHOWER PACK",
    "fieldC" : "false",
    "fieldD" : "01",
    "fieldE" : "true",
    "fieldArrayA" : [ "val1","val2", "val3"]
}

我想查询我的索引并获得以下结果:

IF fieldArrayA.length > 0 并且 val1 在 fieldArrayA 中,那么为 true,否则为 false

所以我想知道是否可以请求我的索引来获得以下结果:

_source" : {
    "fieldA" : "M",
    "fieldB" : "SHOWER PACK",
    "fieldC" : "false",
    "fieldD" : "01",
    "fieldE" : "true",
    "fieldArrayA_as_boolean" : true
}
请问 ElasticSearch 查询应该是什么?

2nd Example:

POST tly-idx_test1/_doc
{
  "fieldA": "M",
  "fieldB": "SHOWER PACK",
  "fieldC": "false",
  "fieldD": "01",
  "fieldE": "true",
  "fieldArrayA": [
    "val1",
    "val2",
    "val3"
  ],
   "fieldArrayB": [
    {"fieldB1":"val1"},
    {"fieldB1":"val2"},
    {"fieldB1":"val3"}
  ]
}
映射如下:

PUT tly-idx_test1
{
  "mappings": {
    "properties": {
      "fieldA": {
        "type": "text"
      },
      "fieldArrayA": {
        "type": "keyword"
      },
     "fieldArrayB": {
      "type": "nested",
      "properties": {
        "fieldB1": {
          "type": "keyword",
          "fields": {
            "text": {
              "type": "text",
              "analyzer": "standard"
              }
            }
          }
        }
     },
      "fieldB": {
        "type": "text"
      },
      "fieldC": {
        "type": "text"
      },
      "fieldD": {
        "type": "text"
      },
      "fieldE": {
        "type": "boolean"
      }
    }
  }
}

如何获得以下结果:

IF fieldArrayB.length > 0 并且 val1  fieldArrayB 中,那么为 true,否则为 false

_source" : {
              "fieldA" : "M",
              "fieldB" : "SHOWER PACK",
              "fieldC" : "false",
              "fieldD" : "01",
              "fieldE" : "true",
              "fieldArrayB_as_boolean" : true
}
谢谢
英文:

I am using ElasticSearch 8.6.

Here below is my index :

1st Example

_source" : {
"fieldA" : "M",
"fieldB" : "SHOWER PACK",
"fieldC" : "false",
"fieldD" : "01",
"fieldE" : "true",
"fieldArrayA" : [ "val1","val2", "val3"]
}

I would like to query my index and get something like

IF fieldArrayA.length > 0 and val1 in fieldArrayA, THEN true ELSE false

So I would like to know it were possible to request my index to get the following result:

_source" : {
"fieldA" : "M",
"fieldB" : "SHOWER PACK",
"fieldC" : "false",
"fieldD" : "01",
"fieldE" : "true",
"fieldArrayA_as_boolean" : true
}

what would be the ElasticSearch query ?

2nd Example:

POST tly-idx_test1/_doc
{
"fieldA": "M",
"fieldB": "SHOWER PACK",
"fieldC": "false",
"fieldD": "01",
"fieldE": "true",
"fieldArrayA": [
"val1",
"val2",
"val3"
],
"fieldArrayB": [
{"fieldB1":"val1"},
{"fieldB1":"val2"},
{"fieldB1":"val3"}
]
}

The mapping is the following :

PUT tly-idx_test1
{
"mappings": {
"properties": {
"fieldA": {
"type": "text"
},
"fieldArrayA": {
"type": "keyword"
},
"fieldArrayB": {
"type": "nested",
"properties": {
"fieldB1": {
"type": "keyword",
"fields": {
"text": {
"type": "text",
"analyzer": "standard"
}
}
}
}
},
"fieldB": {
"type": "text"
},
"fieldC": {
"type": "text"
},
"fieldD": {
"type": "text"
},
"fieldE": {
"type": "boolean"
}
}
}
}

How to get the following results with

 IF fieldArrayB.length > 0 and val1 in fieldArrayB, THEN true ELSE false

?

  _source" : {
"fieldA" : "M",
"fieldB" : "SHOWER PACK",
"fieldC" : "false",
"fieldD" : "01",
"fieldE" : "true",
"fieldArrayB_as_boolean" : true
}

Thanks

答案1

得分: 1

你可以尝试使用script fields来实现这个。

你想要的只能通过使用Elasticsearch中的脚本来实现。但是脚本不建议使用,因为它们不够高效。

另一个选项是使用Terms Query来进行查询,但你没有想要的 "fieldArrayA_as_boolean" 字段。

不过,你可以获取Terms Query的结果,在你的应用程序中创建逻辑来将这个字段添加到你的回答中,这样从长远来看会更好。

索引:

PUT idx_test
{
"mappings": {
"properties": {
"fieldA": {
"type": "text"
},
"fieldArrayA": {
"type": "keyword"
},
"fieldB": {
"type": "text"
},
"fieldC": {
"type": "text"
},
"fieldD": {
"type": "text"
},
"fieldE": {
"type": "boolean"
}
}
}
}

添加文档:

POST idx_test/_doc
{
"fieldA": "M",
"fieldB": "SHOWER PACK",
"fieldC": "false",
"fieldD": "01",
"fieldE": "true",
"fieldArrayA": [
"val1",
"val2",
"val3"
]
}

查询:

{
"size": 10,
"_source": "*",
"script_fields": {
"fieldArrayA_as_boolean": {
"script": {
"source": """
def list = doc['fieldArrayA'];
return list.size() > 0 && list.contains('val1');
"""
}
}
},
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"source": """
def list = doc['fieldArrayA'];
return list.size() > 0 && list.contains('val1');
"""
}
}
}
]
}
}
}

使用Terms Query的示例:

{
"size": 10,
"query": {
"terms": {
"fieldArrayA.keyword": [
"val1"
]
}
}
}
英文:

You can try this using script fields.

What you want is only possible via script using Elasticsearch. However scripts are not recommended as they are not performant.
The other option is to make a query with Terms Query, but you don't have the field you want the "fieldArrayA_as_boolean".

Still you can receive the results of the Terms Query and in your application create a logic to add this field in your answer, which would be better thinking in the long term.

Indexing:

PUT idx_test
{
"mappings": {
"properties": {
"fieldA": {
"type": "text"
},
"fieldArrayA": {
"type": "keyword"
},
"fieldB": {
"type": "text"
},
"fieldC": {
"type": "text"
},
"fieldD": {
"type": "text"
},
"fieldE": {
"type": "boolean"
}
}
}
}
POST idx_test/_doc
{
"fieldA": "M",
"fieldB": "SHOWER PACK",
"fieldC": "false",
"fieldD": "01",
"fieldE": "true",
"fieldArrayA": [
"val1",
"val2",
"val3"
]
}

Query:

{
"size": 10,
"_source": "*",
"script_fields": {
"fieldArrayA_as_boolean": {
"script": {
"source": """
def list = doc['fieldArrayA'];
return list.size() > 0 && list.contains('val1');
"""
}
}
},
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"source": """
def list = doc['fieldArrayA'];
return list.size() > 0 && list.contains('val1');
"""
}
}
}
]
}
}
}

Example with Terms Query

{
"size": 10,
"query": {
"terms": {
"fieldArrayA.keyword": [
"val1"
]
}
}
} 

huangapple
  • 本文由 发表于 2023年3月31日 20:48:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75898734.html
匿名

发表评论

匿名网友

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

确定