es针对nested类型数据无法进行过滤查询的问题记录

es,针对,nested,类型,数据,无法,进行,过滤,查询,问题,记录 · 浏览次数 : 21

小编点评

## Summary of the problem and solutions: **Problem:** * The code was trying to search a nested data map (`data`) in Elasticsearch, but it was unable to access the nested fields. **Solutions:** 1. **Modified code logic:** * Changed the search query to use `nestedQuery` with `MatchQuery` on the nested field and a path to the outer document. * This allows the search to access the nested fields using the specified path. 2. **Use of `Nested Query`:** * Nested Query is a specific search operator used for handling nested documents. * It allows searching nested fields by using path expressions and filtering based on specific values. 3. **Example query:** * The new query uses `nestedQuery` to search the `data` map, using the path "data" and filtering based on the value of "input18779". **Additional Notes:** * The `nested` data type is a special Elasticsearch data type for handling nested documents. * When searching nested fields, you need to use specific path expressions to access them. * The `path` parameter in `nestedQuery` allows you to specify the path to the nested field. * The `score_mode` parameter is set to `none` to ensure that the search focuses on the nested field rather than the outer document.

正文

问题描述

es中存在有一个名为task_data_1的索引,其字段映射关系如下所示:
{
    "task_data_1" : {
        "mappings" : {
        "dynamic_templates" : [
            {
                "dates" : {
                "match_mapping_type" : "date",
                    "mapping" : {
                        "type" : "date"
                    }
                }
            },
            {
            "doubles" : {
                "match_mapping_type" : "double",
                "mapping" : {
                    "type" : "double"
                    }
                }
            },
            {
            "objects" : {
                "match_mapping_type" : "object",
                "mapping" : {
                    "type" : "object"
                    }
                }
            },
            {
            "longs" : {
                "match_mapping_type" : "long",
                "mapping" : {
                    "type" : "integer"
                }
                }
            },
            {
            "strings" : {
                "match" : "*",
                "match_mapping_type" : "string",
                "mapping" : {
                    "type" : "keyword"
                }
            }
            }
            ],
            "properties" : {
                "createUsername" : {
                    "type" : "keyword"
                },
                "data" : {
                    "type" : "nested",
                    "dynamic" : "true",
                    "properties" : {
                        "daterange102110" : {
                            "type" : "date"
                        },
                        "input18779" : {
                            "type" : "keyword"
                        },
                        "rate48025" : {
                            "type" : "integer"
                        },
                        "textarea24212" : {
                            "type" : "keyword"
                        },
                        "textarea38172" : {
                            "type" : "keyword"
                        },
                        "timerange47544" : {
                            "type" : "keyword"
                        },
                        "url" : {
                            "type" : "keyword"
                        }
                    }
                },
                "formId" : {
                    "type" : "long",
                    "store" : true
                },
                "updateUsername" : {
                    "type" : "keyword"
                }
            }
        }
    }
}
通过createUsername、updateUsername、formId等字段可以正常进行过滤查询功能,但是data这个map中的所有字段都无法正常进行过滤查询功能。

解决过程

起初,我是直接用map中对应的字段名进行过滤查询,编写的代码生成的DSL如下所示:
POST task_data_1/_search
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "input18779": {
              "value": "3213",
              "boost": 1
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "sort": [
    {
      "createTime": {
        "order": "desc"
      }
    }
  ],
  "track_total_hits": 2147483647
}
这样子的查询语法有很明显的问题,因为input32768这个字段是嵌套在data这个map中的,直接使用input32768这个字段名是无法查询到对应数据的。
 
发现问题后,我修改了代码逻辑,而后生成的DSL如下所示:
POST task_data_1/_search
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "data.input18779": {
              "value": "3213",
              "boost": 1
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "sort": [
    {
      "createTime": {
        "order": "desc"
      }
    }
  ],
  "track_total_hits": 2147483647
}
这样子的查询语法,从表现上看是没有任何问题的,但依然查不出数据。
 
后来我到kibana查询了该索引的字段映射关系,就是上文中的这一段json数据:
{
    "task_data_1" : {
        "mappings" : {
        "dynamic_templates" : [
            {
                "dates" : {
                "match_mapping_type" : "date",
                    "mapping" : {
                        "type" : "date"
                    }
                }
            },
            {
            "doubles" : {
                "match_mapping_type" : "double",
                "mapping" : {
                    "type" : "double"
                    }
                }
            },
            {
            "objects" : {
                "match_mapping_type" : "object",
                "mapping" : {
                    "type" : "object"
                    }
                }
            },
            {
            "longs" : {
                "match_mapping_type" : "long",
                "mapping" : {
                    "type" : "integer"
                }
                }
            },
            {
            "strings" : {
                "match" : "*",
                "match_mapping_type" : "string",
                "mapping" : {
                    "type" : "keyword"
                }
            }
            }
            ],
            "properties" : {
                "createUsername" : {
                    "type" : "keyword"
                },
                "data" : {
                    "type" : "nested",
                    "dynamic" : "true",
                    "properties" : {
                        "daterange102110" : {
                            "type" : "date"
                        },
                        "input18779" : {
                            "type" : "keyword"
                        },
                        "rate48025" : {
                            "type" : "integer"
                        },
                        "textarea24212" : {
                            "type" : "keyword"
                        },
                        "textarea38172" : {
                            "type" : "keyword"
                        },
                        "timerange47544" : {
                            "type" : "keyword"
                        },
                        "url" : {
                            "type" : "keyword"
                        }
                    }
                },
                "formId" : {
                    "type" : "long",
                    "store" : true
                },
                "updateUsername" : {
                    "type" : "keyword"
                }
            }
        }
    }
}
从这段json数据中可以发现,data这个map的类型是nested。
 
查资料后得知,在 Elasticsearch 中,"nested" 类型是一种特殊的数据类型,用于处理嵌套文档(nested documents)。
针对这种类型的数据,需要使用 Nested Query 结合 Match Query 或 Term Query 等查询类型来搜索嵌套字段。
 
因此,我对代码做出类似如下整改:
queryBuilder.must(QueryBuilders.nestedQuery("data", QueryBuilders.termQuery(queryFieldName, item.getFilterValue()), ScoreMode.None));
 
主要是使用到了 Nested Query,之后生成的DSL如下所示:
POST task_data_1/_search
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "term": {
                "data.input18779": {
                  "value": "3213",
                  "boost": 1
                }
              }
            },
            "path": "data",
            "ignore_unmapped": false,
            "score_mode": "none",
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "sort": [
    {
      "createTime": {
        "order": "desc"
      }
    }
  ],
  "track_total_hits": 2147483647
}
此时,对应的数据结果就能够被查询出来了。

总结

在 Elasticsearch 中,"nested" 类型是一种特殊的数据类型,用于处理嵌套文档(nested documents)。
 
对于 "nested" 类型的字段,它包含的子字段(metadata)在查询时需要使用特定的嵌套查询来进行搜索操作,简单的查询无法直接搜索到嵌套字段的内容。
以我提供的数据映射为例,数据中的 "data" map 中的每个字段(如 "daterange102110"、 "input18779" 等)都无法直接进行搜索,因为 Elasticsearch 默认不会对嵌套字段进行索引。
 
如果你希望能够对嵌套字段进行搜索,你需要使用嵌套查询。例如,可以使用 Nested Query 结合 Match Query 或 Term Query 等查询类型来搜索嵌套字段。

与es针对nested类型数据无法进行过滤查询的问题记录相似的内容:

es针对nested类型数据无法进行过滤查询的问题记录

问题描述 es中存在有一个名为task_data_1的索引,其字段映射关系如下所示: { "task_data_1" : { "mappings" : { "dynamic_templates" : [ { "dates" : { "match_mapping_type" : "date", "ma

【升职加薪秘籍】我在服务监控方面的实践(8)-elasticsearch 性能监控与分析手段

> 大家好,我是蓝胖子,之前讲了mysql,redis中间件的监控,今天我们再来看看另一个基础组件elasticsearch,如何对它进行监控,当你思考如何对一个组件进行监控时,四大黄金指标会告诉你答案,我们同样会从四大黄金指标给出的维度进行分析。 针对es做的性能分析,用四大黄金指标原则,我们可以

ElasticSearch 实现分词全文检索 - 搜素关键字自动补全(Completion Suggest)

ES使用Completion Suggest 做关键字自动补全时,实际应用中搜索性能更加高效,建议多开一个子字段,如下示例,假设要根据title字段做关键字自动补全,不要改原字段的类型,多开一个子字段title.suggest,类型设置为completion,然后之后的suggest针对title.suggest字段做操作

LLM应用实战:当KBQA集成LLM(二)

本文主要是针对KBQA方案基于LLM实现存在的问题进行优化,主要涉及到图谱存储至Es,且支持Es的向量检索,还有解决了一部分基于属性值倒查实体的场景,且效果相对提升。

ElasticSearch 实现分词全文检索 - id、ids、prefix、fuzzy、wildcard、range、regexp 查询

fuzzy查询:模糊查询,我们输入字符的大概,ES就可以 wildcard 查询:通配查询,和MySQL中的 like 差不多,可以在查询时,在字符串中指定通配符 * 和占位符? range 查询:范围查询,只针对数值类型,对某一个Field进行大于或小于的范围指定查询 regexp 查询: 正则查询,通过你编写的正则表达式去匹配内容

ES 2024 新特性

ECMAScript 2024 新特性 ECMAScript 2024, the 15th edition, added facilities for resizing and transferring ArrayBuffers and SharedArrayBuffers; added a new

es请求方式调用

Es基础 关系: ElasticSearch-> mysql index (索引)-> 数据库 Documents(文档) -> row(行) Fileds(字段)-> column 正排索引 id 内容,类似表格 倒排索引 :keywords : ids Postman访问实例 创建索引:创建库

[转帖]龙叔学ES:Elasticsearch XPACK安全认证

https://juejin.cn/post/7081994919237287950 本文已参与「新人创作礼」活动,一起开启掘金创作之路。 Elasticsearch往往存有公司大量的数据,如果安全不过关,那么就会有严重的数据安全隐患。 Elasticsearch 的安全认证方式有不少,如http-

[转帖]ES集群开启X-pack认证

https://www.cnblogs.com/jclty/p/12913996.html 1.下载 1 # wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-linux-x86_64.tar.

ElasticSearch 实现分词全文检索 - 概述

ES 是一个使用Java语言并且基于Lucene编写的搜索引擎框架,他提供了分布式的全文搜索功能,提供了一个统一的基于Restful风格的WEB接口,官方客户端也对多种语言都提供了相应的API。