ElasticSearch检索你的数据(六)

ElasticSearch检索你的数据(六)

搜索模板

搜索模板存储了运行不同变量的查询模板。如果你使用ElasticSearch作为查询后端,你可以将来自搜索栏的用户输入传递给搜索模板的变量参数。这可以让你在不公开ElasticSearch查询语法的情况下来运行查询。

如果自定义的应用使用了ElasticSearch,那么查询模板可以在不修改你应用代码的情况下修改ElasticSearch的搜索。

创建一个搜索模板

对于创建和修改搜索模板,你可以使用create stored script API

请求的source支持与搜索API的请求体一样的参数。source也支持Mustache变量,通常用两个大括号括起来:{{my-var}}。当你运行模板搜索的时候,ElasticSearch会用param的值替换这个变量。

搜索模板必须使用一个 "lang":"mustache"

以下请求创建一个idmy-search-template的搜索模板。

curl -X PUT "localhost:9200/_scripts/my-search-template?pretty" -H 'Content-Type: application/json' -d'
{
  "script": {
    "lang": "mustache",
    "source": {
      "query": {
        "match": {
          "message": "{{query_string}}"
        }
      },
      "from": "{{from}}",
      "size": "{{size}}"
    },
    "params": {
      "query_string": "My query string"
    }
  }
}
'

Elasticsearch 将搜索模板存储为集群状态下的 Mustache 脚本。 Elasticsearch 在模板脚本上下文中编译搜索模板。限制或禁用脚本的设置也会影响搜索模板。

验证一个搜索模板

使用render search template API利用不同的param测试搜索模板

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "id": "my-search-template",
  "params": {
    "query_string": "hello world",
    "from": 20,
    "size": 10
  }
}
'

当参数被渲染的时候,模板会输出搜索请求体。

{
  "template_output": {
    "query": {
      "match": {
        "message": "hello world"
      }
    },
    "from": "20",
    "size": "10"
  }
}

您还可以使用 API 来测试内联模板。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
    "source": {
      "query": {
        "match": {
          "message": "{{query_string}}"
        }
      },
      "from": "{{from}}",
      "size": "{{size}}"
    },
  "params": {
    "query_string": "hello world",
    "from": 20,
    "size": 10
  }
}
'

运行一个模板搜索

使用search template API来运行一个使用搜索模板的搜索。你可以为每个请求指定不同的param

curl -X GET "localhost:9200/my-index/_search/template?pretty" -H 'Content-Type: application/json' -d'
{
  "id": "my-search-template",
  "params": {
    "query_string": "hello world",
    "from": 0,
    "size": 10
  }
}
'

响应使用与search API 响应一样的属性。

{
  "took": 36,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.5753642,
    "hits": [
      {
        "_index": "my-index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "message": "hello world"
        }
      }
    ]
  }
}

运行多个模板搜索

使用multi search template API在一个单独的请求中运行多个模板搜索。与多个单独搜索相比,这些请求的开销通常更少,速度更快。

curl -X GET "localhost:9200/my-index/_msearch/template?pretty" -H 'Content-Type: application/json' -d'
{ }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }}
'

获取一个搜索模板

使用get stored script API获取一个搜索模板。

curl -X GET "localhost:9200/_scripts/my-search-template?pretty"

使用cluster state API获取搜索模板列表和其他的脚本。

curl -X GET "localhost:9200/_cluster/state/metadata?pretty&filter_path=metadata.stored_scripts&pretty"

删除搜索模板

使用delete stored script API删除一个搜索模板。

curl -X DELETE "localhost:9200/_scripts/my-search-template?pretty"

设置默认值

根据以下语法为变量设置默认值。

{{my-var}}{{^my-var}}default value{{/my-var}}

如果搜索模板未在其参数中指定值,则搜索将使用默认值。例如,以下模板设置了 fromsize 的默认值。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "query": {
      "match": {
        "message": "{{query_string}}"
      }
    },
    "from": "{{from}}{{^from}}0{{/from}}",
    "size": "{{size}}{{^size}}10{{/size}}"
  },
  "params": {
    "query_string": "hello world"
  }
}
'

URL编码字符串

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

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "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}} 函数将数组值连接为逗号分隔的字符串。例如,以下模板连接两个电子邮件地址。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "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"
      }
    }
  }
}

您还可以指定自定义分隔符。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "query": {
      "range": {
        "user.effective.date": {
          "gte": "{{date.min}}",
          "lte": "{{date.max}}",
          "format": "{{#join delimiter=\u0027||\u0027}}date.formats{{/join delimiter=\u0027||\u0027}}"
	      }
      }
    }
  },
  "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"
        }
      }
    }
  }

转换JSON

使用 {{#toJson}} 函数将变量值转换为其 JSON 表示。

例如,以下模板使用 {{#toJson}} 传递数组。为确保请求正文是有效的 JSON,source以字符串格式编写。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "source": "{ \"query\": { \"terms\": { \"tags\": {{#toJson}}tags{{/toJson}} }}}",
  "params": {
    "tags": [
      "prod",
      "es01"
    ]
  }
}
'

模板呈现为:

{
  "template_output": {
    "query": {
      "terms": {
        "tags": [
          "prod",
          "es01"
        ]
      }
    }
  }
}

您还可以使用 {{#toJson}} 来传递对象。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "source": "{ \"query\": {{#toJson}}my_query{{/toJson}} }",
  "params": {
    "my_query": {
      "match_all": { }
    }
  }
}
'

模板呈现为:

{
  "template_output" : {
    "query" : {
      "match_all" : { }
    }
  }
}

您还可以传递对象数组。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "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"
            }
          }
        ]
      }
    }
  }
}

使用条件

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

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

如果条件变量为真,Elasticsearch 会显示其内容。例如,如果 year_scope 为真,以下模板将搜索过去一年的数据。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "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_scopefalse,则模板搜索任何时间段的数据。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "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": false,
    "user_id": "kimchy"
  }
}
'

模板呈现为:

{
  "template_output" : {
    "query" : {
      "bool" : {
        "filter" : [
          {
            "term" : {
              "user.id" : "kimchy"
            }
          }
        ]
      }
    }
  }
}

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

{{#condition}}if content{{/condition}} {{^condition}}else content{{/condition}}

例如,如果 year_scope 为真,以下模板将搜索过去一年的数据。否则,它将搜索过去一天的数据。

curl -X POST "localhost:9200/_render/template?pretty" -H 'Content-Type: application/json' -d'
{
  "source": "{ \"query\": { \"bool\": { \"filter\": [ { \"range\": { \"@timestamp\": { \"gte\": {{#year_scope}} \"now-1y/d\" {{/year_scope}} {{^year_scope}} \"now-1d/d\" {{/year_scope}} , \"lt\": \"now/d\" }}}, { \"term\": { \"user.id\": \"{{user_id}}\" }}]}}}",
  "params": {
    "year_scope": true,
    "user_id": "kimchy"
  }
}
'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值