検索テンプレート
検索テンプレートは、異なる変数で実行できる保存された検索です。
Elasticsearchを検索バックエンドとして使用する場合、検索バーからのユーザー入力を検索テンプレートのパラメータとして渡すことができます。これにより、ユーザーにElasticsearchのクエリ構文を公開することなく検索を実行できます。
カスタムアプリケーションにElasticsearchを使用する場合、検索テンプレートを使用すると、アプリのコードを変更することなく検索を変更できます。
検索テンプレートの作成
検索テンプレートを作成または更新するには、create stored script APIを使用します。
リクエストのsource
は、search APIのリクエストボディと同じパラメータをサポートします。source
は、オープンソースプロジェクトmustache.javaからのMustache変数も受け入れます。
通常、Mustache変数は二重波括弧で囲まれています: {{my-var}}
。テンプレート化された検索を実行すると、Elasticsearchはこれらの変数をparams
からの値に置き換えます。mustache構文の詳細については、Mustache.jsマニュアルを参照してください。検索テンプレートはlang
のmustache
を使用する必要があります。
次のリクエストは、id
のmy-search-template
を持つ検索テンプレートを作成します。
Python
resp = client.put_script(
id="my-search-template",
script={
"lang": "mustache",
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
}
},
)
print(resp)
Ruby
response = client.put_script(
id: 'my-search-template',
body: {
script: {
lang: 'mustache',
source: {
query: {
match: {
message: '{{query_string}}'
}
},
from: '{{from}}',
size: '{{size}}'
}
}
}
)
puts response
Js
const response = await client.putScript({
id: "my-search-template",
script: {
lang: "mustache",
source: {
query: {
match: {
message: "{{query_string}}",
},
},
from: "{{from}}",
size: "{{size}}",
},
},
});
console.log(response);
コンソール
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
}
}
}
Elasticsearchは、検索テンプレートをクラスタ状態のMustache scriptsとして保存します。Elasticsearchはtemplate
スクリプトコンテキストで検索テンプレートをコンパイルします。スクリプトを制限または無効にする設定は、検索テンプレートにも影響します。
検索テンプレートの検証
異なるparams
でテンプレートをテストするには、render search template APIを使用します。
Python
resp = client.render_search_template(
id="my-search-template",
params={
"query_string": "hello world",
"from": 20,
"size": 10
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
id: 'my-search-template',
params: {
query_string: 'hello world',
from: 20,
size: 10
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
id: "my-search-template",
params: {
query_string: "hello world",
from: 20,
size: 10,
},
});
console.log(response);
コンソール
POST _render/template
{
"id": "my-search-template",
"params": {
"query_string": "hello world",
"from": 20,
"size": 10
}
}
レンダリングされると、テンプレートはsearch request bodyを出力します。
コンソール-結果
{
"template_output": {
"query": {
"match": {
"message": "hello world"
}
},
"from": "20",
"size": "10"
}
}
APIを使用してインラインテンプレートをテストすることもできます。
Python
resp = client.render_search_template(
source={
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
},
params={
"query_string": "hello world",
"from": 20,
"size": 10
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: {
query: {
match: {
message: '{{query_string}}'
}
},
from: '{{from}}',
size: '{{size}}'
},
params: {
query_string: 'hello world',
from: 20,
size: 10
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: {
query: {
match: {
message: "{{query_string}}",
},
},
from: "{{from}}",
size: "{{size}}",
},
params: {
query_string: "hello world",
from: 20,
size: 10,
},
});
console.log(response);
コンソール
POST _render/template
{
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
},
"params": {
"query_string": "hello world",
"from": 20,
"size": 10
}
}
テンプレート化された検索の実行
検索テンプレートを使用して検索を実行するには、search template APIを使用します。各リクエストで異なるparams
を指定できます。
Python
resp = client.search_template(
index="my-index",
id="my-search-template",
params={
"query_string": "hello world",
"from": 0,
"size": 10
},
)
print(resp)
Ruby
response = client.search_template(
index: 'my-index',
body: {
id: 'my-search-template',
params: {
query_string: 'hello world',
from: 0,
size: 10
}
}
)
puts response
Js
const response = await client.searchTemplate({
index: "my-index",
id: "my-search-template",
params: {
query_string: "hello world",
from: 0,
size: 10,
},
});
console.log(response);
コンソール
GET my-index/_search/template
{
"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",
"_id": "1",
"_score": 0.5753642,
"_source": {
"message": "hello world"
}
}
]
}
}
複数のテンプレート化された検索の実行
単一のリクエストで複数のテンプレート化された検索を実行するには、multi search template APIを使用します。これらのリクエストは、複数の個別の検索よりもオーバーヘッドが少なく、速度が速いことがよくあります。
Python
resp = client.msearch_template(
index="my-index",
search_templates=[
{},
{
"id": "my-search-template",
"params": {
"query_string": "hello world",
"from": 0,
"size": 10
}
},
{},
{
"id": "my-other-search-template",
"params": {
"query_type": "match_all"
}
}
],
)
print(resp)
Ruby
response = client.msearch_template(
index: 'my-index',
body: [
{},
{
id: 'my-search-template',
params: {
query_string: 'hello world',
from: 0,
size: 10
}
},
{},
{
id: 'my-other-search-template',
params: {
query_type: 'match_all'
}
}
]
)
puts response
Js
const response = await client.msearchTemplate({
index: "my-index",
search_templates: [
{},
{
id: "my-search-template",
params: {
query_string: "hello world",
from: 0,
size: 10,
},
},
{},
{
id: "my-other-search-template",
params: {
query_type: "match_all",
},
},
],
});
console.log(response);
コンソール
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" }}
検索テンプレートの取得
検索テンプレートを取得するには、get stored script APIを使用します。
Python
resp = client.get_script(
id="my-search-template",
)
print(resp)
Ruby
response = client.get_script(
id: 'my-search-template'
)
puts response
Js
const response = await client.getScript({
id: "my-search-template",
});
console.log(response);
コンソール
GET _scripts/my-search-template
すべての検索テンプレートと他の保存されたスクリプトのリストを取得するには、cluster state APIを使用します。
Python
resp = client.cluster.state(
metric="metadata",
pretty=True,
filter_path="metadata.stored_scripts",
)
print(resp)
Ruby
response = client.cluster.state(
metric: 'metadata',
pretty: true,
filter_path: 'metadata.stored_scripts'
)
puts response
Js
const response = await client.cluster.state({
metric: "metadata",
pretty: "true",
filter_path: "metadata.stored_scripts",
});
console.log(response);
コンソール
GET _cluster/state/metadata?pretty&filter_path=metadata.stored_scripts
検索テンプレートの削除
検索テンプレートを削除するには、delete stored script APIを使用します。
Python
resp = client.delete_script(
id="my-search-template",
)
print(resp)
Ruby
response = client.delete_script(
id: 'my-search-template'
)
puts response
Js
const response = await client.deleteScript({
id: "my-search-template",
});
console.log(response);
コンソール
DELETE _scripts/my-search-template
デフォルト値の設定
変数のデフォルト値を設定するには、次の構文を使用します:
Mustache
{{my-var}}{{^my-var}}default value{{/my-var}}
テンプレート化された検索がparams
に値を指定しない場合、検索は代わりにデフォルト値を使用します。たとえば、次のテンプレートはfrom
とsize
のデフォルトを設定します。
Python
resp = client.render_search_template(
source={
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}{{^from}}0{{/from}}",
"size": "{{size}}{{^size}}10{{/size}}"
},
params={
"query_string": "hello world"
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: {
query: {
match: {
message: '{{query_string}}'
}
},
from: '{{from}}{{^from}}0{{/from}}',
size: '{{size}}{{^size}}10{{/size}}'
},
params: {
query_string: 'hello world'
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: {
query: {
match: {
message: "{{query_string}}",
},
},
from: "{{from}}{{^from}}0{{/from}}",
size: "{{size}}{{^size}}10{{/size}}",
},
params: {
query_string: "hello world",
},
});
console.log(response);
コンソール
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エンコードされた文字列
#### Python
``````python
resp = client.render_search_template(
source={
"query": {
"term": {
"url.full": "{{#url}}{{host}}/{{page}}{{/url}}"
}
}
},
params={
"host": "http://example.com",
"page": "hello-world"
},
)
print(resp)
`
Ruby
response = client.render_search_template(
body: {
source: {
query: {
term: {
'url.full' => '{{#url}}{{host}}/{{page}}{{/url}}'
}
}
},
params: {
host: 'http://example.com',
page: 'hello-world'
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: {
query: {
term: {
"url.full": "{{#url}}{{host}}/{{page}}{{/url}}",
},
},
},
params: {
host: "http://example.com",
page: "hello-world",
},
});
console.log(response);
コンソール
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"
}
}
}
}
値の連結
#### Python
``````python
resp = client.render_search_template(
source={
"query": {
"match": {
"user.group.emails": "{{#join}}emails{{/join}}"
}
}
},
params={
"emails": [
"[email protected]",
"[email protected]"
]
},
)
print(resp)
`
Ruby
response = client.render_search_template(
body: {
source: {
query: {
match: {
'user.group.emails' => '{{#join}}emails{{/join}}'
}
}
},
params: {
emails: [
'[email protected]',
'[email protected]'
]
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: {
query: {
match: {
"user.group.emails": "{{#join}}emails{{/join}}",
},
},
},
params: {
emails: ["[email protected]", "[email protected]"],
},
});
console.log(response);
コンソール
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]"
}
}
}
}
カスタム区切り文字を指定することもできます。
Python
resp = client.render_search_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"
]
}
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
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'
]
}
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
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"],
},
},
});
console.log(response);
コンソール
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"
}
}
}
}
}
JSONへの変換
たとえば、次のテンプレートは`````{{#toJson}}`````を使用して配列を渡します。リクエストボディが有効なJSONであることを確認するために、`````source`````は文字列形式で書かれます。
#### Python
``````python
resp = client.render_search_template(
source="{ \"query\": { \"terms\": { \"tags\": {{#toJson}}tags{{/toJson}} }}}",
params={
"tags": [
"prod",
"es01"
]
},
)
print(resp)
`
Ruby
response = client.render_search_template(
body: {
source: '{ "query": { "terms": { "tags": {{#toJson}}tags{{/toJson}} }}}',
params: {
tags: [
'prod',
'es01'
]
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: '{ "query": { "terms": { "tags": {{#toJson}}tags{{/toJson}} }}}',
params: {
tags: ["prod", "es01"],
},
});
console.log(response);
コンソール
POST _render/template
{
"source": "{ \"query\": { \"terms\": { \"tags\": {{#toJson}}tags{{/toJson}} }}}",
"params": {
"tags": [
"prod",
"es01"
]
}
}
コンソール-結果
{
"template_output": {
"query": {
"terms": {
"tags": [
"prod",
"es01"
]
}
}
}
}
オブジェクトを渡すために{{#toJson}}
を使用することもできます。
Python
resp = client.render_search_template(
source="{ \"query\": {{#toJson}}my_query{{/toJson}} }",
params={
"my_query": {
"match_all": {}
}
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: '{ "query": {{#toJson}}my_query{{/toJson}} }',
params: {
my_query: {
match_all: {}
}
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: '{ "query": {{#toJson}}my_query{{/toJson}} }',
params: {
my_query: {
match_all: {},
},
},
});
console.log(response);
コンソール
POST _render/template
{
"source": "{ \"query\": {{#toJson}}my_query{{/toJson}} }",
"params": {
"my_query": {
"match_all": { }
}
}
}
コンソール-結果
{
"template_output" : {
"query" : {
"match_all" : { }
}
}
}
オブジェクトの配列を渡すこともできます。
Python
resp = client.render_search_template(
source="{ \"query\": { \"bool\": { \"must\": {{#toJson}}clauses{{/toJson}} }}}",
params={
"clauses": [
{
"term": {
"user.id": "kimchy"
}
},
{
"term": {
"url.domain": "example.com"
}
}
]
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: '{ "query": { "bool": { "must": {{#toJson}}clauses{{/toJson}} }}}',
params: {
clauses: [
{
term: {
'user.id' => 'kimchy'
}
},
{
term: {
'url.domain' => 'example.com'
}
}
]
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: '{ "query": { "bool": { "must": {{#toJson}}clauses{{/toJson}} }}}',
params: {
clauses: [
{
term: {
"user.id": "kimchy",
},
},
{
term: {
"url.domain": "example.com",
},
},
],
},
});
console.log(response);
コンソール
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"
}
}
]
}
}
}
}
条件の使用
if条件を作成するには、次の構文を使用します:
Mustache
{{#condition}}content{{/condition}}
条件変数がtrue
の場合、Elasticsearchはその内容を表示します。たとえば、次のテンプレートはyear_scope
がtrue
の場合、過去1年のデータを検索します。
Python
resp = client.render_search_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"
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
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'
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
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",
},
});
console.log(response);
コンソール
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"
}
}
]
}
}
}
}
#### Python
``````python
resp = client.render_search_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": False,
"user_id": "kimchy"
},
)
print(resp)
`
Ruby
response = client.render_search_template(
body: {
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'
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
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",
},
});
console.log(response);
コンソール
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": false,
"user_id": "kimchy"
}
}
コンソール-結果
{
"template_output" : {
"query" : {
"bool" : {
"filter" : [
{
"term" : {
"user.id" : "kimchy"
}
}
]
}
}
}
}
if-else条件を作成するには、次の構文を使用します:
Mustache
{{#condition}}if content{{/condition}} {{^condition}}else content{{/condition}}
たとえば、次のテンプレートはyear_scope
がtrue
の場合、過去1年のデータを検索します。それ以外の場合は、過去1日のデータを検索します。
Python
resp = client.render_search_template(
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"
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
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'
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
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",
},
});
console.log(response);
コンソール
POST _render/template
{
"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"
}
}
Mustacheを使用した検索テンプレートの例
mustacheテンプレート言語は、テンプレート内で使用できるさまざまなタグタイプを定義します。次のセクションでは、これらのタグタイプのいくつかを説明し、Elasticsearchのsearch templatesでの使用例を提供します。
Mustache変数
Mustacheタグは通常、二重波括弧で囲まれています。mustache変数: {{my-variable}}
は、mustacheタグの一種です。テンプレート化された検索を実行すると、Elasticsearchはこれらの変数をparams
からの値に置き換えます。
たとえば、次の検索テンプレートを考えてみてください:
Python
resp = client.put_script(
id="my-search-template",
script={
"lang": "mustache",
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
}
},
)
print(resp)
Ruby
response = client.put_script(
id: 'my-search-template',
body: {
script: {
lang: 'mustache',
source: {
query: {
match: {
message: '{{query_string}}'
}
},
from: '{{from}}',
size: '{{size}}'
}
}
}
)
puts response
Js
const response = await client.putScript({
id: "my-search-template",
script: {
lang: "mustache",
source: {
query: {
match: {
message: "{{query_string}}",
},
},
from: "{{from}}",
size: "{{size}}",
},
},
});
console.log(response);
コンソール
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
}
}
}
上記の検索テンプレートをparams
でテストします:
Python
resp = client.render_search_template(
id="my-search-template",
params={
"query_string": "hello world",
"from": 20,
"size": 10
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
id: 'my-search-template',
params: {
query_string: 'hello world',
from: 20,
size: 10
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
id: "my-search-template",
params: {
query_string: "hello world",
from: 20,
size: 10,
},
});
console.log(response);
コンソール
POST _render/template
{
"id": "my-search-template",
"params": {
"query_string": "hello world",
"from": 20,
"size": 10
}
}
レンダリングされると、{{query_string}}
はmessage
でhello world
に置き換えられます。
コンソール-結果
{
"template_output": {
"query": {
"match": {
"message": "hello world"
}
},
"from": "20",
"size": "10"
}
}
検索テンプレートがquery_string
に値を渡さない場合、メッセージは空の文字列に置き換えられます。
たとえば:
Python
resp = client.render_search_template(
id="my-search-template",
params={
"from": 20,
"size": 10
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
id: 'my-search-template',
params: {
from: 20,
size: 10
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
id: "my-search-template",
params: {
from: 20,
size: 10,
},
});
console.log(response);
コンソール
POST _render/template
{
"id": "my-search-template",
"params": {
"from": 20,
"size": 10
}
}
レンダリングされると、テンプレートは次のように出力されます:
コンソール-結果
{
"template_output": {
"query": {
"match": {
"message": ""
}
},
"from": "20",
"size": "10"
}
}
セクション
セクションもMustacheタグの一種です。検索テンプレートでsections
を使用することができます。セクションは{{#my-section-variable}}
で始まり、{{/my-section-variable}}
で終わります。
次の検索テンプレートは、ネストされたオブジェクトを使用したセクションの例を示しています:
Python
resp = client.render_search_template(
source="\n {\n \"query\": {\n \"match\": {\n {{#query_message}}\n {{#query_string}}\n \"message\": \"Hello {{#first_name_section}}{{first_name}}{{/first_name_section}} {{#last_name_section}}{{last_name}}{{/last_name_section}}\"\n {{/query_string}}\n {{/query_message}}\n }\n }\n }\n ",
params={
"query_message": {
"query_string": {
"first_name_section": {
"first_name": "John"
},
"last_name_section": {
"last_name": "kimchy"
}
}
}
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: "\n {\n \"query\": {\n \"match\": {\n {{#query_message}}\n {{#query_string}}\n \"message\": \"Hello {{#first_name_section}}{{first_name}}{{/first_name_section}} {{#last_name_section}}{{last_name}}{{/last_name_section}}\"\n {{/query_string}}\n {{/query_message}}\n }\n }\n }\n ",
params: {
query_message: {
query_string: {
first_name_section: {
first_name: 'John'
},
last_name_section: {
last_name: 'kimchy'
}
}
}
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source:
'\n {\n "query": {\n "match": {\n {{#query_message}}\n {{#query_string}}\n "message": "Hello {{#first_name_section}}{{first_name}}{{/first_name_section}} {{#last_name_section}}{{last_name}}{{/last_name_section}}"\n {{/query_string}}\n {{/query_message}}\n }\n }\n }\n ',
params: {
query_message: {
query_string: {
first_name_section: {
first_name: "John",
},
last_name_section: {
last_name: "kimchy",
},
},
},
},
});
console.log(response);
コンソール
POST _render/template
{
"source":
"""
{
"query": {
"match": {
{{#query_message}}
{{#query_string}}
"message": "Hello {{#first_name_section}}{{first_name}}{{/first_name_section}} {{#last_name_section}}{{last_name}}{{/last_name_section}}"
{{/query_string}}
{{/query_message}}
}
}
}
""",
"params": {
"query_message": {
"query_string": {
"first_name_section": {"first_name": "John"},
"last_name_section": {"last_name": "kimchy"}
}
}
}
}
コンソール-結果
{
"template_output": {
"query": {
"match": {
"message": "Hello John kimchy"
}
}
}
}
リスト
オブジェクトのリストを渡し、検索テンプレート内の各アイテムをループ処理できます。
たとえば、次の検索テンプレートはsectionsを組み合わせて、すべてのユーザー名に一致します:
Python
resp = client.put_script(
id="my-search-template",
script={
"lang": "mustache",
"source": {
"query": {
"multi_match": {
"query": "{{query_string}}",
"fields": "[{{#text_fields}}{{user_name}},{{/text_fields}}]"
}
}
}
},
)
print(resp)
Ruby
response = client.put_script(
id: 'my-search-template',
body: {
script: {
lang: 'mustache',
source: {
query: {
multi_match: {
query: '{{query_string}}',
fields: '[{{#text_fields}}{{user_name}},{{/text_fields}}]'
}
}
}
}
}
)
puts response
Js
const response = await client.putScript({
id: "my-search-template",
script: {
lang: "mustache",
source: {
query: {
multi_match: {
query: "{{query_string}}",
fields: "[{{#text_fields}}{{user_name}},{{/text_fields}}]",
},
},
},
},
});
console.log(response);
コンソール
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source": {
"query":{
"multi_match":{
"query": "{{query_string}}",
"fields": """[{{#text_fields}}{{user_name}},{{/text_fields}}]"""
}
}
}
}
}
テンプレートをテストします:
Python
resp = client.render_search_template(
id="my-search-template",
params={
"query_string": "My string",
"text_fields": [
{
"user_name": "John"
},
{
"user_name": "kimchy"
}
]
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
id: 'my-search-template',
params: {
query_string: 'My string',
text_fields: [
{
user_name: 'John'
},
{
user_name: 'kimchy'
}
]
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
id: "my-search-template",
params: {
query_string: "My string",
text_fields: [
{
user_name: "John",
},
{
user_name: "kimchy",
},
],
},
});
console.log(response);
コンソール
POST _render/template
{
"id": "my-search-template",
"params": {
"query_string": "My string",
"text_fields": [
{
"user_name": "John"
},
{
"user_name": "kimchy"
}
]
}
}
レンダリングされると、テンプレートは次のように出力されます:
コンソール-結果
{
"template_output": {
"query": {
"multi_match": {
"query": "My string",
"fields": "[John,kimchy,]"
}
}
}
}
上記はトレーリングカンマの問題を引き起こし、無効なJSONを引き起こします。回避策は、inverted sectionを含め、配列の最後のアイテムであることを確認するために変数を追加することです。
たとえば:
Python
resp = client.put_script(
id="my-search-template",
script={
"lang": "mustache",
"source": {
"query": {
"multi_match": {
"query": "{{query_string}}",
"fields": "[{{#text_fields}}{{user_name}}{{^last}},{{/last}}{{/text_fields}}]"
}
}
}
},
)
print(resp)
Ruby
response = client.put_script(
id: 'my-search-template',
body: {
script: {
lang: 'mustache',
source: {
query: {
multi_match: {
query: '{{query_string}}',
fields: '[{{#text_fields}}{{user_name}}{{^last}},{{/last}}{{/text_fields}}]'
}
}
}
}
}
)
puts response
Js
const response = await client.putScript({
id: "my-search-template",
script: {
lang: "mustache",
source: {
query: {
multi_match: {
query: "{{query_string}}",
fields:
"[{{#text_fields}}{{user_name}}{{^last}},{{/last}}{{/text_fields}}]",
},
},
},
},
});
console.log(response);
コンソール
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source": {
"query":{
"multi_match":{
"query": "{{query_string}}",
"fields": """[{{#text_fields}}{{user_name}}{{^last}},{{/last}}{{/text_fields}}]"""
}
}
}
}
}
#### Python
``````python
resp = client.render_search_template(
id="my-search-template",
params={
"query_string": "My string",
"text_fields": [
{
"user_name": "John",
"last": False
},
{
"user_name": "kimchy",
"last": True
}
]
},
)
print(resp)
`
Ruby
response = client.render_search_template(
body: {
id: 'my-search-template',
params: {
query_string: 'My string',
text_fields: [
{
user_name: 'John',
last: false
},
{
user_name: 'kimchy',
last: true
}
]
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
id: "my-search-template",
params: {
query_string: "My string",
text_fields: [
{
user_name: "John",
last: false,
},
{
user_name: "kimchy",
last: true,
},
],
},
});
console.log(response);
コンソール
POST _render/template
{
"id": "my-search-template",
"params": {
"query_string": "My string",
"text_fields": [
{
"user_name": "John",
"last": false
},
{
"user_name": "kimchy",
"last": true
}
]
}
}
レンダリングされると、テンプレートは次のように出力されます:
コンソール-結果
{
"template_output": {
"query": {
"multi_match": {
"query": "My string",
"fields": "[John,kimchy]"
}
}
}
}
ラムダ
Elasticsearchには、テキストを特定の形式に変換するための事前構築されたカスタム関数があります。
mustacheラムダの使用方法については、Url encode strings、Concatenate values、およびConvert to jsonの例を確認してください。
反転セクション
反転セクションは、一度だけ値を設定したい場合に便利です。
反転セクションを使用するには、次の構文を使用します:
Mustache
{{^my-variable}} content {{/my-variable}}
たとえば、次の検索テンプレートでは、name_exists
がfalse
の場合、message
がHello World
で設定され、そうでない場合は空の文字列に設定されます。
Python
resp = client.render_search_template(
source={
"query": {
"match": {
"message": "{{^name_exists}}Hello World{{/name_exists}}"
}
}
},
params={
"name_exists": False
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: {
query: {
match: {
message: '{{^name_exists}}Hello World{{/name_exists}}'
}
}
},
params: {
name_exists: false
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: {
query: {
match: {
message: "{{^name_exists}}Hello World{{/name_exists}}",
},
},
},
params: {
name_exists: false,
},
});
console.log(response);
コンソール
POST _render/template
{
"source": {
"query": {
"match": {
"message": "{{^name_exists}}Hello World{{/name_exists}}"
}
}
},
"params": {
"name_exists": false
}
}
これらは、conditionsやdefault valuesと組み合わせることもできます。
たとえば、次の検索テンプレートでは、name_exists
がtrue
の場合、{{query_string}}
の値が置き換えられます。name_exists
がfalse
の場合、デフォルト値World
に設定されます。
Python
resp = client.render_search_template(
source={
"query": {
"match": {
"message": "Hello {{#name_exists}}{{query_string}}{{/name_exists}}{{^name_exists}}World{{/name_exists}}"
}
}
},
params={
"query_string": "Kimchy",
"name_exists": True
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
source: {
query: {
match: {
message: 'Hello {{#name_exists}}{{query_string}}{{/name_exists}}{{^name_exists}}World{{/name_exists}}'
}
}
},
params: {
query_string: 'Kimchy',
name_exists: true
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
source: {
query: {
match: {
message:
"Hello {{#name_exists}}{{query_string}}{{/name_exists}}{{^name_exists}}World{{/name_exists}}",
},
},
},
params: {
query_string: "Kimchy",
name_exists: true,
},
});
console.log(response);
コンソール
POST _render/template
{
"source": {
"query": {
"match": {
"message": "Hello {{#name_exists}}{{query_string}}{{/name_exists}}{{^name_exists}}World{{/name_exists}}"
}
}
},
"params": {
"query_string": "Kimchy",
"name_exists": true
}
}
コンソール-結果
{
"template_output": {
"query": {
"match": {
"message": "Hello Kimchy"
}
}
}
}
区切り文字の設定
デフォルトの区切り文字: 二重波括弧{{my-variable}}
を検索テンプレート内の任意のカスタム区切り文字に変更できます。
たとえば、次の検索テンプレートはデフォルトの区切り文字を単一の丸括弧(query_string)
に変更します。
Python
resp = client.put_script(
id="my-search-template",
script={
"lang": "mustache",
"source": "\n {\n \"query\": {\n \"match\": {\n {{=( )=}}\n \"message\": \"(query_string)\"\n (={{ }}=)\n }\n }\n }\n "
},
)
print(resp)
Ruby
response = client.put_script(
id: 'my-search-template',
body: {
script: {
lang: 'mustache',
source: "\n {\n \"query\": {\n \"match\": {\n {{=( )=}}\n \"message\": \"(query_string)\"\n (={{ }}=)\n }\n }\n }\n "
}
}
)
puts response
Js
const response = await client.putScript({
id: "my-search-template",
script: {
lang: "mustache",
source:
'\n {\n "query": {\n "match": {\n {{=( )=}}\n "message": "(query_string)"\n (={{ }}=)\n }\n }\n }\n ',
},
});
console.log(response);
コンソール
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source":
"""
{
"query": {
"match": {
{{=( )=}}
"message": "(query_string)"
(={{ }}=)
}
}
}
"""
}
}
新しい区切り文字でテンプレートをテストします:
Python
resp = client.render_search_template(
id="my-search-template",
params={
"query_string": "hello world"
},
)
print(resp)
Ruby
response = client.render_search_template(
body: {
id: 'my-search-template',
params: {
query_string: 'hello world'
}
}
)
puts response
Js
const response = await client.renderSearchTemplate({
id: "my-search-template",
params: {
query_string: "hello world",
},
});
console.log(response);
コンソール
POST _render/template
{
"id": "my-search-template",
"params": {
"query_string": "hello world"
}
}
レンダリングされると、テンプレートは次のように出力されます:
コンソール-結果
{
"template_output": {
"query": {
"match": {
"message": "hello world"
}
}
}
}
サポートされていない機能
次のmustache機能は、Elasticsearchの検索テンプレートではサポートされていません:
- 部分