Elasticsearch (ES) 搜索引擎: 搜索模板:创建/修改/验证/运行搜索模板、模板参数传递、JSON数组传递

原文链接:https://xiets.blog.csdn.net/article/details/144221801

版权声明:原创文章禁止转载

专栏目录:Elasticsearch 专栏(总目录)

搜索模板相关链接:

搜索模板是一个存储搜索,用户可以使用不同的参数运行。对于一些逻辑复杂的查询,可以先把查询逻辑封装为一个搜索模板,然后只需要传入不同的参数就能搜索出不同的结果。

1. 创建/获取/验证搜索模板

创建或更新搜索模板,需要使用创建存储脚本API:Create or update stored script API。此 API 不仅可以创建搜索模板,还可以创建 Painless 脚本。

1.1 创建/修改搜索模板

创建/修改搜索模板:

PUT /_scripts/my-search-template                // 创建/修改脚本, 指定 脚本ID (搜索模板ID), 这里指定的模板ID为 "my-search-template"
{
    "script": {
        "lang": "mustache",                     // 脚本语言类型, 搜索模板 使用 "mustache"
        "source": {                             // (对象 或 字符串) 模板内容 (运行搜索模板时将作为搜索请求的Body)
            "from": "{{from}}",                 // 以双大括号 {{param}} 的方式引用参数
            "size": "{{size}}",
            "query": {
                "match": {
                    "message": "{{query_string}}"
                }
            }
        }
    }
}

// 搜索模板 的 脚本内容(source), 可以以对象的方式提供, 也可以把对象序列化为字符串提供。
// 如果 source 提供的是对象, 则会把对象序列化为字符串存储。
// 执行搜索时, 应用了实际参数的 source 将作为搜索请求的 Body。

1.2 获取搜索模板

要获取搜索模板,请使用获取存储脚本的API:Get stored script API

获取搜索模板:

GET /_scripts/my-search-template

// 返回
{
    "_id" : "my-search-template",
    "found" : true,
    "script" : {
        "lang" : "mustache",
        "source" : "{\"from\":\"{{from}}\",\"size\":\"{{size}}\",\"query\":{\"match\":{\"message\":\"{{query_string}}\"}}}",
        "options" : {
            "content_type" : "application/json;charset=utf-8"
        }
    }
}

要获取所有搜索模板和其他存储脚本的列表,请使用集群状态API:Cluster state API

获取所有存储的脚本:

GET /_cluster/state/metadata?pretty&filter_path=metadata.stored_scripts

// 返回
{
    "metadata" : {
        "stored_scripts" : {
            "my-search-template" : {
                "lang" : "mustache",
                "source" : "{\"from\":\"{{from}}\",\"size\":\"{{size}}\",\"query\":{\"match\":{\"message\":\"{{query_string}}\"}}}",
                "options" : {
                    "content_type" : "application/json;charset=utf-8"
                }
            },
            "search_hotel" : {
                "lang" : "mustache",
                "source" : "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"name\":\"{{query_string}}\"}},{\"range\":{\"price\":{\"lte\":\"{{max_price}}\"}}}]}}}",
                "options" : {
                    "content_type" : "application/json;charset=utf-8"
                }
            }
        }
    }
}

1.3 验证搜索模板

要测试搜索模板在搜索请求时的具体请求Body,可以用渲染搜索模板API:render search template API

验证搜索模板:

POST /_render/template
{
    "id": "my-search-template",             // 指定搜索模板ID
    "params": {                             // 传递参数
        "from": 20,
        "size": 10,
        "query_string": "Hello World"
    }
}

// 返回
{
    "template_output": {        // 此对象将作为搜索请求的Body
        "from": "20",
        "size": "10",
        "query": {
            "match": {
                "message": "Hello World"
            }
        }
    }
}

还可以使用渲染 API 测试内联模板(不指定模板ID,而是直接给出模板内容):

POST /_render/template
{
    "source": {                                 // 模板内容 (对象 或 字符串)
        "query": {
            "match": {
                "message": "{{query_string}}"
            }
        },
        "from": "{{from}}",
        "size": "{{size}}"
    },
    "params": {
        "query_string": "Hello World",
        "from": 20,
        "size": 10
    }
}

// 返回
{
    "template_output": {
        "query": {
            "match": {
                "message": "Hello World"
            }
        },
        "from": "20",
        "size": "10"
    }
}

1.4 删除模板

删除模板:

DELETE /_scripts/my-search-template

2. 模板参数

搜索模板的参数以双大括号 {{param}} 的形式引用,可以设置默认值、对字符串进行URL编码、传递 JSON 对象/数组类型的参数、连接数组值、使用条件判断 等。

2.1 参数默认值

要设置参数的默认值,使用以下语法:

{{param}}{{^param}}default_value{{/param}}

运行搜索模板时,如果没有传递参数值,则使用默认值:

POST /_render/template
{
    "source": {
        "from": "{{from}}{{^from}}0{{/from}}",
        "size": "{{size}}{{^size}}10{{/size}}",
        "query": {
            "match": {
                "message": "{{query_string}}"
            }
        }
    },
    "params": {
        "query_string": "Hello World"
    }
}

// 返回
{
    "template_output": {
        "from": "0",
        "size": "10",
        "query": {
            "match": {
                "message": "Hello World"
            }
        }
    }
}

2.2 URL 编码字符串

搜索模板脚本可以使用内置的函数,使用函数的语法:

{{#function}}argument{{/function}}

使用 {{#url}} 函数对字符串进行 URL 编码:

POST /_render/template
{
    "source": {
        "query": {
            "term": {
                "url.full": "{{#url}}{{host}}/{{page}}{{/url}}"
            }
        }
    },
    "params": {
        "host": "https://xiets.blog.csdn.net",
        "page": "article/details/131849457"
    }
}

// 返回
{
    "template_output": {
        "query": {
            "term": {
                "url.full": "https%3A%2F%2Fxiets.blog.csdn.net%2Farticle%2Fdetails%2F131849457"
            }
        }
    }
}

2.3 JSON 对象/数组参数

使用 {{#toJson}} 函数可以将变量值转换为其 JSON 表示形式,为了确保请求 Body 是有效的 JSON,source 以字符串格式编写:

POST /_render/template
{
    "source": "{ \"query\": { \"terms\": { \"tags\": {{#toJson}}tags{{/toJson}} } }, \"from\": {{from}}, \"size\": {{size}} }",
    "params": {
        "from": 0,
        "size": 10,
        "tags": [ "hello", "world" ]
    }
}

// 返回
{
    "template_output": {
        "query": {
            "terms": {
                "tags": [ "hello", "world" ]
            }
        },
        "from": 0,
        "size": 10
    }
}

2.4 连接数组值

使用 {{#join}} 函数将数组值连接为逗号,分隔的字符串。例如,以下模板连接两个电子邮件地址:

POST /_render/template
{
    "source": {
        "query": {
            "match": {
                "user.group.emails": "{{#join}}emails{{/join}}"
            }
        }
    },
    "params": {
        "emails": [ "user1@example.com", "user_one@example.com" ]
    }
}

// 返回
{
    "template_output": {
        "query": {
            "match": {
                "user.group.emails": "user1@example.com,user_one@example.com"
            }
        }
    }
}

2.5 使用条件判断

要创建 if 条件,请使用以下语法:

{{#condition}}content{{/condition}}

上面的 condition 是布尔类型的参数,如果此参数的值为 true 则显示内容(content),否则不显示内容。

POST /_render/template
{
    "source": "{ \"query\": { \"bool\": { \"filter\": [ {{#year_scope}} { \"range\": { \"@timestamp\": { \"gte\": \"now-1y/d\", \"lt\": \"now/d\" } } }, {{/year_scope}} { \"term\": { \"user.id\": \"{{user_id}}\" }}]}}}",
    "params": {
        "year_scope": true,
        "user_id": "kimchy"
    }
}

// 返回
{
    "template_output": {
        "query": {
            "bool": {
                "filter": [
                    {
                        "range": {
                            "@timestamp": {
                                "gte": "now-1y/d",
                                "lt": "now/d"
                            }
                        }
                    },
                    {
                        "term": {
                            "user.id": "kimchy"
                        }
                    }
                ]
            }
        }
    }
}

// 如果 "year_scope" 传递 false, 则返回
{
    "template_output": {
        "query": {
            "bool": {
                "filter": [
                    {
                        "term": {
                            "user.id": "kimchy"
                        }
                    }
                ]
            }
        }
    }
}

3. 运行搜索模板

要使用搜索模板运行搜索,请使用搜索模板 API:Search template API,用户可以 params 为每个请求指定不同的参数内容。

运行搜索模板请求格式:

POST /<index>/_search/template              // 指定在哪个索引中运行搜索模板
{
    "id": "<template_id>",                  // 模板ID
    "params": {                             // 传递参数
        "from": 0,
        "size": 10,
        "query_string": "hello world"
    }
}

为方便演示,下面创建示例索引和文档:

// 创建索引
PUT /hotel
{
    "mappings": {
        "properties": {
            "name": {
                "type": "text"
            },
            "price": {
                "type": "double"
            }
        }
    }
}

// 写入一些文档
PUT /hotel/_doc/001
{"name": "龙门国际大酒店", "price": 300.00}

PUT /hotel/_doc/002
{"name": "龙门精选假日酒店", "price": 200.00}

PUT /hotel/_doc/003
{"name": "龙门客栈古风酒店", "price": 350.00}

PUT /hotel/_doc/004
{"name": "悦来时尚宾馆", "price": 99.00}

PUT /hotel/_doc/005
{"name": "悦来文雅大酒店", "price": 550.00}

PUT /hotel/_doc/006
{"name": "烟雨楼文雅假日酒店", "price": 600.00}

创建搜索模板:

PUT /_scripts/search_hotel
{
    "script": {
        "lang": "mustache",
        "source": {
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "name": "{{query_string}}"
                            }
                        },
                        {
                            "range": {
                                "price": {
                                    "lte": "{{max_price}}"
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}

查询模板:

GET /_scripts/search_hotel

// 返回
{
    "_id" : "search_hotel",
    "found" : true,
    "script" : {
        "lang" : "mustache",
        "source" : "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"name\":\"{{query_string}}\"}},{\"range\":{\"price\":{\"lte\":\"{{max_price}}\"}}}]}}}",
        "options" : {
            "content_type" : "application/json;charset=utf-8"
        }
    }
}

运行模板:

POST /hotel/_search/template
{
    "id": "search_hotel",
    "params": {
        "query_string": "龙门",
        "max_price": 300
    }
}

// 返回
{
    // ...,
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 2.4251623,
        "hits": [
            {
                "_index": "hotel",
                "_id": "001",
                "_score": 2.4251623,
                "_source": {
                    "name": "龙门国际大酒店",
                    "price": 300
                }
            },
            {
                "_index": "hotel",
                "_id": "002",
                "_score": 2.3494902,
                "_source": {
                    "name": "龙门精选假日酒店",
                    "price": 200
                }
            }
        ]
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢TS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值