Elastic:查询数组时如何只返回匹配的数组元素

简介: 简单数组是不能设置inner_hits的,这一点我查询了很多资料,并没有找到答案,最后咨询了业界大佬,了解到,简单数组目前并不支持这种操作

1 数组查询

ES的查询单位是doc,所以当我们查询数组时,虽然满足条件的是其中某一部分元素,但是这些元素以及这个数组都是属于这个doc的,所以会全部返回。如果我们要返回匹配的元素。那么就需要借助一些手段来实现。
查询

GET arr_json/_search
{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "match": {
          "tags.name": "ok"
        }
      }
    }
  }
}

查询结果

"hits" : [
      {
        "_index" : "arr_json",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.9808291,
        "_source" : {
          "tags" : [
            {
              "id" : 1,
              "name" : "ok"
            },
            {
              "id" : 2,
              "name" : "fine"
            },
            {
              "id" : 3,
              "name" : "right"
            }
          ]
        }
      }
    ]

2 json型数组只返回匹配的数组元素

添加数据

PUT arr_json
{
  "mappings": {
    "properties": {
      "tags": {
        "type": "nested"
      }
    }
  }
}

PUT arr_json/_doc/1
{"tags":[
  {"id":1,"name":"ok"},
  {"id":2,"name":"fine"},
  {"id":3,"name":"right"}
  ]
}

通过inner_hit以及ignore_unmapped来实现:

GET arr_json/_search
{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "match": {
          "tags.name": "ok"
        }
      },
      "inner_hits": {
        "ignore_unmapped": false
      }
    }
  }
}

返回结果,注意要求的数据是在inner_hit中

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.9808291,
    "hits" : [
      {
        "_index" : "arr_json",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.9808291,
        "_source" : {
          "tags" : [
            {
              "id" : 1,
              "name" : "ok"
            },
            {
              "id" : 2,
              "name" : "fine"
            },
            {
              "id" : 3,
              "name" : "right"
            }
          ]
        },
        "inner_hits" : {
          "tags" : {
            "hits" : {
              "total" : {
                "value" : 1,
                "relation" : "eq"
              },
              "max_score" : 0.9808291,
              "hits" : [
                {
                  "_index" : "arr_json",
                  "_type" : "_doc",
                  "_id" : "1",
                  "_nested" : {
                    "field" : "tags",
                    "offset" : 0
                  },
                  "_score" : 0.9808291,
                  "_source" : {
                    "name" : "ok",
                    "id" : 1
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

3 inner_hits解读

The parent-join and nested features allow the return of documents that have matches in a different scope. In the parent/child case, parent documents are returned based on matches in child documents or child documents are returned based on matches in parent documents. In the nested case, documents are returned based on matches in nested inner objects.

In both cases, the actual matches in the different scopes that caused a document to be returned are hidden. In many cases, it’s very useful to know which inner nested objects (in the case of nested) or children/parent documents (in the case of parent/child) caused certain information to be returned. The inner hits feature can be used for this. This feature returns per search hit in the search response additional nested hits that caused a search hit to match in a different scope.

Inner hits can be used by defining an inner_hits definition on a nested, has_child or has_parent query and filter. The structure looks like this:

"<query>" : {
  "inner_hits" : {
    <inner_hits_options>
  }
}

译文:
父连接和嵌套功能允许返回在不同范围内有匹配的文档。在父/子的情况下,父文档根据子文档中的匹配结果被返回,或者子文档根据父文档中的匹配结果被返回。在嵌套的情况下,文件是根据嵌套的内部对象中的匹配来返回的。

在这两种情况下,导致文档被返回的不同作用域中的实际匹配是隐藏的。在许多情况下,知道哪个内部嵌套对象(在嵌套的情况下)或子/父文档(在父/子的情况下)导致某些信息被返回是非常有用的。内部命中特征可以用于此。这个功能在搜索响应中返回每一个导致搜索命中在不同范围内匹配的额外嵌套命中。

内部命中可以通过在一个嵌套的,has_child或者has_parent查询和过滤器上定义一个inner_hits定义来使用。该结构看起来像这样。

"<query>" : {
  "inner_hits" : {
    <inner_hits_options>
  }
}

所以可以看出,inner_hits只适用nested和join结构的数据

4 简单数组只返回匹配的数组元素

PUT test3/_doc/1
{
  "tags": [
    "ok",
    "fine",
    "right"
  ]
}

简单数组是不能设置inner_hits的,这一点我查询了很多资料,并没有找到答案,最后咨询了业界大佬,了解到,简单数组目前并不支持这种操作

如果你有任何想法,也可以留言探讨

目录
相关文章
|
2月前
查找数组中最大的元素值
【10月更文挑战第29天】查找数组中最大的元素值。
37 4
|
5月前
|
算法 Java
LeetCode第28题找出字符串中第一个匹配项的下标
这篇文章介绍了LeetCode第28题"找出字符串中第一个匹配项的下标"的两种解法:暴力解法和KMP算法,并解释了KMP算法通过构建前缀表来提高字符串搜索的效率。
LeetCode第28题找出字符串中第一个匹配项的下标
|
6月前
|
存储 语音技术 索引
语音识别,列表的定义语法,列表[],列表的下标索引,从列表中取出来特定的数据,name[0]就是索引,反向索引,头部是-1,my[1][1],嵌套列表使用, 列表常用操作, 函数一样,需引入
语音识别,列表的定义语法,列表[],列表的下标索引,从列表中取出来特定的数据,name[0]就是索引,反向索引,头部是-1,my[1][1],嵌套列表使用, 列表常用操作, 函数一样,需引入
|
8月前
|
存储
数据结构---串(赋值,求子串,比较,定位)
数据结构---串(赋值,求子串,比较,定位)
82 4
数据结构---串(赋值,求子串,比较,定位)
es6查询数组某元素出现次数
es6查询数组某元素出现次数
128 1
|
C++ 容器
【C++】字符串遍历的三种方式
【C++】字符串遍历的三种方式
|
算法 Python
一日一技:包含元组的列表,对第一个元素升序第二个元素降序
一日一技:包含元组的列表,对第一个元素升序第二个元素降序
110 0
|
算法
LeetCode:28. 找出字符串中第一个匹配项的下标
题目描述:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
101 0
|
索引
Elastic实战:nested查询与数组同一元素匹配多个值
之前有同学实际生产中遇到了一个问题,题目本身不涉及生产环境上的问题,纯粹的DSL,但是因为是实际数据,因此数据量上会大很多,也增加了排错的难度。下面我们具体看下这个问题,让大家具体体会下实际生产的问题与训练题之间的区别在哪儿。
128 0
Elastic实战:nested查询与数组同一元素匹配多个值
|
Scala 开发者