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"
}
}
}