技术标签: Elastic Elasticsearch elasticsearch 大数据
我们发现一些用户经常编写了一些非常冗长和复杂的查询 - 在很多情况下,相同的查询会一遍又一遍地执行,但是会有一些不同的值作为参数来查询。在这种情况下,我们觉得使用一个 search template(搜索模板)来做这样的工作非常合适。搜索模板允许你使用可在执行时定义的参数定义查询。
Search template 的好处是:
首先,我们来定义一个 search template 来看看它到底是什么东西。使用_scripts端点将模板存储在集群状态中。在 search template中使用的语言叫做 mustache。
POST _scripts/my_search_template
{
"script": {
"lang": "mustache",
"source": {
"query": {
"match": {
"{
{my_field}}": "{
{my_value}}"
}
}
}
}
}
在这里,我们定义了一个叫做 my_search_template 的 search template。如果我们想更新这个 search template,我们可以直接进行修改,然后再次运行上面的命令即可。
我们可以试验如下的命令来验证我们的 search template:
POST _render/template
{
"id": "my_search_template",
"params": {
"my_field": "city",
"my_value": "Beijing"
}
}
上述命令输出搜索请求正文:
{
"template_output": {
"query": {
"match": {
"city": "Beijing"
}
}
}
}
我们也可以使用如下的 API 来测试 inline templates:
POST _render/template
{
"source": {
"query": {
"match": {
"{
{my_field}}": "{
{my_value}}"
}
}
},
"params": {
"my_field": "city",
"my_value": "Beijing"
}
}
上面的命令将返回和上述命令一样的结果。
要使用搜索模板运行搜索,请使用搜索模板 API。 你可以为每个请求指定不同的参数。
在 match 的字段里,我们定义了两个参数:my_field 及 my_value。下面,我们来首先建立一个叫做 twitter 的索引:
PUT twitter/_doc/1
{
"user" : "双榆树-张三",
"message" : "今儿天气不错啊,出去转转去",
"uid" : 2,
"age" : 20,
"city" : "北京",
"province" : "北京",
"country" : "中国",
"address" : "中国北京市海淀区",
"location" : {
"lat" : "39.970718",
"lon" : "116.325747"
}
}
PUT twitter/_doc/2
{
"user" : "虹桥-老吴",
"message" : "好友来了都今天我生日,好友来了,什么 birthday happy 就成!",
"uid" : 7,
"age" : 90,
"city" : "上海",
"province" : "上海",
"country" : "中国",
"address" : "中国上海市闵行区",
"location" : {
"lat" : "31.175927",
"lon" : "121.383328"
}
}
我们这里把上面的两个文档存于到 twitter 的i ndex 之中。我们现在可以使用我们刚才定义的 search template 来进行搜索:
GET twitter/_search/template
{
"id": "my_search_template",
"params": {
"my_field": "city",
"my_value": "北京"
}
}
显示的结果是:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.9808292,
"hits" : [
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.9808292,
"_source" : {
"user" : "双榆树-张三",
"message" : "今儿天气不错啊,出去转转去",
"uid" : 2,
"age" : 20,
"city" : "北京",
"province" : "北京",
"country" : "中国",
"address" : "中国北京市海淀区",
"location" : {
"lat" : "39.970718",
"lon" : "116.325747"
}
}
}
]
}
}
显示它只显示了我们的 city 为北京的一个文档,另外一个上海的文档没有做任何的显示。说明我们定义的 search template 是工作的。
要使用单个请求运行多个模板化搜索,请使用多搜索模板 API。 与多个单独的搜索相比,这些请求通常具有更少的开销和更快的速度:
GET my-index/_msearch/template
{ }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }}
要为变量设置默认值,请使用以下语法:
{
{my-var}}{
{^my-var}}default value{
{/my-var}}
如果模板化搜索未在其参数中指定值,则搜索将使用默认值。 例如,以下模板设置了 from 和 size 的默认值。
POST _render/template
{
"source": {
"query": {
"match": {
"message": "{
{query_string}}"
}
},
"from": "{
{from}}{
{^from}}0{
{/from}}",
"size": "{
{size}}{
{^size}}10{
{/size}}"
},
"params": {
"query_string": "hello world"
}
}
使用 { {#url}} 函数对字符串进行 URL 编码。
POST _render/template
{
"source": {
"query": {
"term": {
"url.full": "{
{#url}}{
{host}}/{
{page}}{
{/url}}"
}
}
},
"params": {
"host": "http://example.com",
"page": "hello-world"
}
}
模板呈现为:
{
"template_output": {
"query": {
"term": {
"url.full": "http%3A%2F%2Fexample.com%2Fhello-world"
}
}
}
}
使用 { {#join}} 函数将数组值连接为逗号分隔的字符串。 例如,以下模板连接两个电子邮件地址。
POST _render/template
{
"source": {
"query": {
"match": {
"user.group.emails": "{
{#join}}emails{
{/join}}"
}
}
},
"params": {
"emails": [ "[email protected]", "[email protected]" ]
}
}
模板呈现为:
{
"template_output": {
"query": {
"match": {
"user.group.emails": "[email protected],[email protected]"
}
}
}
}
你还可以指定自定义分隔符。
POST _render/template
{
"source": {
"query": {
"range": {
"user.effective.date": {
"gte": "{
{date.min}}",
"lte": "{
{date.max}}",
"format": "{
{#join delimiter='||'}}date.formats{
{/join delimiter='||'}}"
}
}
}
},
"params": {
"date": {
"min": "2098",
"max": "06/05/2099",
"formats": ["dd/MM/yyyy", "yyyy"]
}
}
}
模板呈现为:
{
"template_output": {
"query": {
"range": {
"user.effective.date": {
"gte": "2098",
"lte": "06/05/2099",
"format": "dd/MM/yyyy||yyyy"
}
}
}
}
}
使用 { {#toJson}} 函数将变量值转换为其 JSON 表示形式。
例如,以下模板使用 { {#toJson}} 传递数组。 为了确保请求体是有效的 JSON,source 以字符串格式编写。
POST _render/template
{
"source": "{ \"query\": { \"terms\": { \"tags\": {
{#toJson}}tags{
{/toJson}} }}}",
"params": {
"tags": [
"prod",
"es01"
]
}
}
模板呈现为:
{
"template_output": {
"query": {
"terms": {
"tags": [
"prod",
"es01"
]
}
}
}
}
你还可以使用 { {#toJson}} 传递对象。
POST _render/template
{
"source": "{ \"query\": {
{#toJson}}my_query{
{/toJson}} }",
"params": {
"my_query": {
"match_all": { }
}
}
}
模板呈现为:
{
"template_output" : {
"query" : {
"match_all" : { }
}
}
}
你还可以传递一个对象数组:
POST _render/template
{
"source": "{ \"query\": { \"bool\": { \"must\": {
{#toJson}}clauses{
{/toJson}} }}}",
"params": {
"clauses": [
{
"term": {
"user.id": "kimchy"
}
},
{
"term": {
"url.domain": "example.com"
}
}
]
}
}
模板呈现为:
{
"template_output": {
"query": {
"bool": {
"must": [
{
"term": {
"user.id": "kimchy"
}
},
{
"term": {
"url.domain": "example.com"
}
}
]
}
}
}
}
在 Mustache 语言中,它没有 if/else 这样的判断,但是你可以定 section 来跳过它如果那个变量是 false 还是没有被定义:
{
{#param1}}
"This section is skipped if param1 is null or false"
{
{/param1}}
我们定义如下的一个 search template:
POST _scripts/docs_from_beijing_and_age
{
"script": {
"lang": "mustache",
"source":
"""
{
"query": {
"bool": {
"must": [
{
"match": {
"city": "{
{search_term}}"
}
}
{
{#search_age}}
,
{
"range": {
"age": {
"gte": {
{search_age}}
}
}
}
{
{/search_age}}
]
}
}
}
"""
}
}
在这里,我们同时定义了两个变量:search_term 及 search_age。针对 search_age,我们做了一个判断,如果它有定义,及做一个 range 的查询。如果没有定义,就只用 search_term。那么我们来做如下的实验:
GET twitter/_search/template
{
"id": "docs_from_beijing_and_age",
"params": {
"search_term": "北京"
}
}
显示的结果是:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.9808292,
"hits" : [
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.9808292,
"_source" : {
"user" : "双榆树-张三",
"message" : "今儿天气不错啊,出去转转去",
"uid" : 2,
"age" : 20,
"city" : "北京",
"province" : "北京",
"country" : "中国",
"address" : "中国北京市海淀区",
"location" : {
"lat" : "39.970718",
"lon" : "116.325747"
}
}
}
]
}
}
显然,city 为北京的文档已经被搜索到了。如果我们做如下的查询:
GET twitter/_search/template
{
"id": "docs_from_beijing_and_age",
"params": {
"search_term": "北京",
"search_age": "30"
}
}
我们将搜索不到任何的结果,这是因为在这次查询中 search_age 已经被启用,而且在数据库中没有一个文档是来自“北京”,并且年龄大于 30 的。我们可以做如下的查询:
GET twitter/_search/template
{
"id": "docs_from_beijing_and_age",
"params": {
"search_term": "北京",
"search_age": "20"
}
}
那么这次的显示结果为:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.9808292,
"hits" : [
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.9808292,
"_source" : {
"user" : "双榆树-张三",
"message" : "今儿天气不错啊,出去转转去",
"uid" : 2,
"age" : 20,
"city" : "北京",
"province" : "北京",
"country" : "中国",
"address" : "中国北京市海淀区",
"location" : {
"lat" : "39.970718",
"lon" : "116.325747"
}
}
}
]
}
}
显然这次我们搜索到我们想要的结果。
GET _scripts/<templateid>
针对我们的情况:
GET _scripts/docs_from_beijing_and_age
显示的结果为:
{
"_id" : "docs_from_beijing_and_age",
"found" : true,
"script" : {
"lang" : "mustache",
"source" : """
{
"query": {
"bool": {
"must": [
{
"match": {
"city": "{
{search_term}}"
}
}
{
{#search_age}}
,
{
"range": {
"age": {
"gte": {
{search_age}}
}
}
}
{
{/search_age}}
]
}
}
}
"""
}
}
这个正是我们之前定义的一个 search template。
我们可以通过如下的命令来删除一个已经创建的 search template:
DELETE _scripts/<templateid>
我们可以通过 _render 端点来验证我们的 search template。比如:
GET _render/template
{
"source": """
{
"query": {
"bool": {
"must": [
{
"match": {
"city": "{
{search_term}}"
}
}
{
{#search_age}}
,
{
"range": {
"age": {
"gte": {
{search_age}}
}
}
}
{
{/search_age}}
]
}
}
}
""",
"params": {
"search_term": "北京",
"search_age": "20"
}
}
那么显示的结果是:
{
"template_output" : {
"query" : {
"bool" : {
"must" : [
{
"match" : {
"city" : "北京"
}
},
{
"range" : {
"age" : {
"gte" : 20
}
}
}
]
}
}
}
}
显然,这个就是我们想要的结果。
参考:
文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目
文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析
文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat
文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集
文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception
文章浏览阅读358次。1.介绍图的相关概念 图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为: G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图
文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc
文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗
文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver
文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象
文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法
文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范