Elastic:查询时字段runtime fields不显示,如何处理?

举报
wu@55555 发表于 2022/11/19 17:23:11 2022/11/19
【摘要】 很多时候runtime field是结合一起使用的,这时没有任何问题,因为这类需要一般将聚合结果显示出来就行了。但是当我们需要将runtime fields也查询出来时发现查询结果中是不会显示它们的,下面我们通过具体的案例来解决这个问题

0 引言

很多时候runtime field是结合一起使用的,这时没有任何问题,因为这类需要一般将聚合结果显示出来就行了。但是当我们需要将runtime fields也查询出来时发现查询结果中是不会显示它们的,下面我们通过具体的案例来解决这个问题

1 案例

数据

POST test_index3/_bulk
{"index":{}}
{"name":"zhangsan","height":1.78,"weight":44.5}
{"index":{}}
{"name":"lisi","height":1.85,"weight":66}
{"index":{}}
{"name":"wangwu","height":1.82,"weight":84}

要求以runtime field输出bmi字段,且bmi = height / weight,并且要求创建查询模版,输入三个参数name,from,size,最后查出zhangsan的bmi

1.1 案例解决

1、创建查询模版

PUT _scripts/my_search_template
{ 
  "script": {
    "lang": "mustache",
    "source": {
      "runtime_mappings":{
        "bmi": {
          "type": "double",
          "script": {
            "source": """ 
              emit(doc['weight'].value / doc['height'].value);
            """
          }
        }
      },
      "query": {
        "match": {
          "name": "{{name}}"
        }
      },
      "from": "{{from}}",
      "size": "{{size}}"
    }
  }
}

2、调用

GET test_index3/_search/template
{
  "id": "my_search_template",
  "params": {
    "name": "zhangsan",
    "from": 0,
    "size": 10
  }
}

3、查询结果
会发现结果中并没有输出bmi字段

"hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0296195,
    "hits" : [
      {
        "_index" : "test_index3",
        "_type" : "_doc",
        "_id" : "s9IQi30BQVVXVhDNlkxS",
        "_score" : 1.0296195,
        "_source" : {
          "name" : "zhangsan",
          "height" : 1.78,
          "weight" : 44.5
        }
      },
      {
        "_index" : "test_index3",
        "_type" : "_doc",
        "_id" : "hRA0kH0BR7MN8fqkCacz",
        "_score" : 1.0296195,
        "_source" : {
          "name" : "zhangsan",
          "height" : 1.78,
          "weight" : 44.5
        }
      }
    ]
  }

2 原因

这是因为_source中默认是不会显示runtime fields的,所以在查询结果中无法看到bmi,那么有什么方法能让运行时字段显示呢?解决方案就是通过fields属性来设置

3 解决方案

fields属性会对所有的fields起作用,可以通过fields:[“xxx”,“yyy”]的形式来指定需要显示的字段,也可以通过fields:["*"]的形式指定显示所有字段
那么针对上述问题的查询模版就变成了:
这里要注意fields添加的位置,是在script的source中

PUT _scripts/my_search_template
{ 
  "script": {
    "lang": "mustache",
    "source": {
      "fields": [
        "*"
      ],
      "runtime_mappings":{
        "bmi": {
          "type": "double",
          "script": {
            "source": """ 
              emit(doc['weight'].value / doc['height'].value);
            """
          }
        }
      },
      "query": {
        "match": {
          "name": "{{name}}"
        }
      },
      "from": "{{from}}",
      "size": "{{size}}"
    }
  }
}

再次调用查询模版

GET test_index3/_search/template
{
  "id": "my_search_template",
  "params": {
    "name": "zhangsan",
    "from": 0,
    "size": 10
  }
}

查询结果:在结果的最后,发现bmi字段显示出来了

"hits" : [
      {
        "_index" : "test_index3",
        "_type" : "_doc",
        "_id" : "s9IQi30BQVVXVhDNlkxS",
        "_score" : 1.0296195,
        "_source" : {
          "name" : "zhangsan",
          "height" : 1.78,
          "weight" : 44.5
        },
        "fields" : {
          "name" : [
            "zhangsan"
          ],
          "weight" : [
            44.5
          ],
          "name.keyword" : [
            "zhangsan"
          ],
          "height" : [
            1.78
          ],
          "bmi" : [
            25.000000401829073
          ]
        }
      },
      {
        "_index" : "test_index3",
        "_type" : "_doc",
        "_id" : "hRA0kH0BR7MN8fqkCacz",
        "_score" : 1.0296195,
        "_source" : {
          "name" : "zhangsan",
          "height" : 1.78,
          "weight" : 44.5
        },
        "fields" : {
          "name" : [
            "zhangsan"
          ],
          "weight" : [
            44.5
          ],
          "name.keyword" : [
            "zhangsan"
          ],
          "height" : [
            1.78
          ],
          "bmi" : [
            25.000000401829073
          ]
        }
      }
    ]
  }

3.2 template fields

这里要注意一点,在查询模版中,也有一个fields:["*"]属性,如下所示,这个属性是无法达到显示运行时字段的作用的,反而会想不符合条件的字段都查询出来

GET test_index3/_search/template
{
  "id": "my_search_template",
  "template": {
    "fields": [
      "*"
    ]
  },
  "params": {
    "name": "zhangsan",
    "from": 0,
    "size": 10
  }
}

3.3 非查询模版如何显示runtime fields

1、修改mapping,创建runtime fields

PUT test_index3/_mapping
{
  "runtime": {
    "bmi": {
      "type": "double",
      "script": {
        "source": "emit(doc['weight'].value / doc['height'].value)",
        "lang": "painless"
      }
    }
  }
} 

2、查询时添加fields:["*"]

GET test_index3/_search
{
  "fields": [
    "*"
  ],
  "query": {
    "match": {
      "name.keyword": "zhangsan"
    }
  }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。