スクリプトクエリ

Runtime fields は、より柔軟な非常に似た機能を提供します。フィールド値を作成するためのスクリプトを書き、それらは fieldsすべてのクエリ、および 集約 のように、どこでも利用可能です。

提供された script に基づいてドキュメントをフィルタリングします。script クエリは通常、フィルターコンテキスト で使用されます。

スクリプトを使用すると、検索速度が遅くなる可能性があります。詳細は Scripts, caching, and search speed を参照してください。

例のリクエスト

Python

  1. resp = client.search(
  2. query={
  3. "bool": {
  4. "filter": {
  5. "script": {
  6. "script": "\n double amount = doc['amount'].value;\n if (doc['type'].value == 'expense') {\n amount *= -1;\n }\n return amount < 10;\n "
  7. }
  8. }
  9. }
  10. },
  11. )
  12. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. query: {
  4. bool: {
  5. filter: {
  6. script: {
  7. script: "\n double amount = doc['amount'].value;\n if (doc['type'].value == 'expense') {\n amount *= -1;\n }\n return amount < 10;\n "
  8. }
  9. }
  10. }
  11. }
  12. }
  13. )
  14. puts response

Js

  1. const response = await client.search({
  2. query: {
  3. bool: {
  4. filter: {
  5. script: {
  6. script:
  7. "\n double amount = doc['amount'].value;\n if (doc['type'].value == 'expense') {\n amount *= -1;\n }\n return amount < 10;\n ",
  8. },
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

コンソール

  1. GET /_search
  2. {
  3. "query": {
  4. "bool": {
  5. "filter": {
  6. "script": {
  7. "script": """
  8. double amount = doc['amount'].value;
  9. if (doc['type'].value == 'expense') {
  10. amount *= -1;
  11. }
  12. return amount < 10;
  13. """
  14. }
  15. }
  16. }
  17. }
  18. }

ランタイムフィールドを使用することで、検索クエリで同じ結果を得ることができます。_search API の fields パラメータを使用して、同じクエリの一部として値を取得します:

Python

  1. resp = client.search(
  2. runtime_mappings={
  3. "amount.signed": {
  4. "type": "double",
  5. "script": "\n double amount = doc['amount'].value;\n if (doc['type'].value == 'expense') {\n amount *= -1;\n }\n emit(amount);\n "
  6. }
  7. },
  8. query={
  9. "bool": {
  10. "filter": {
  11. "range": {
  12. "amount.signed": {
  13. "lt": 10
  14. }
  15. }
  16. }
  17. }
  18. },
  19. fields=[
  20. {
  21. "field": "amount.signed"
  22. }
  23. ],
  24. )
  25. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. runtime_mappings: {
  4. 'amount.signed' => {
  5. type: 'double',
  6. script: "\n double amount = doc['amount'].value;\n if (doc['type'].value == 'expense') {\n amount *= -1;\n }\n emit(amount);\n "
  7. }
  8. },
  9. query: {
  10. bool: {
  11. filter: {
  12. range: {
  13. 'amount.signed' => {
  14. lt: 10
  15. }
  16. }
  17. }
  18. }
  19. },
  20. fields: [
  21. {
  22. field: 'amount.signed'
  23. }
  24. ]
  25. }
  26. )
  27. puts response

Js

  1. const response = await client.search({
  2. runtime_mappings: {
  3. "amount.signed": {
  4. type: "double",
  5. script:
  6. "\n double amount = doc['amount'].value;\n if (doc['type'].value == 'expense') {\n amount *= -1;\n }\n emit(amount);\n ",
  7. },
  8. },
  9. query: {
  10. bool: {
  11. filter: {
  12. range: {
  13. "amount.signed": {
  14. lt: 10,
  15. },
  16. },
  17. },
  18. },
  19. },
  20. fields: [
  21. {
  22. field: "amount.signed",
  23. },
  24. ],
  25. });
  26. console.log(response);

コンソール

  1. GET /_search
  2. {
  3. "runtime_mappings": {
  4. "amount.signed": {
  5. "type": "double",
  6. "script": """
  7. double amount = doc['amount'].value;
  8. if (doc['type'].value == 'expense') {
  9. amount *= -1;
  10. }
  11. emit(amount);
  12. """
  13. }
  14. },
  15. "query": {
  16. "bool": {
  17. "filter": {
  18. "range": {
  19. "amount.signed": { "lt": 10 }
  20. }
  21. }
  22. }
  23. },
  24. "fields": [{"field": "amount.signed"}]
  25. }

スクリプトのトップレベルパラメータ

  • script
  • (必須、script object) クエリとして実行するスクリプトを含みます。このスクリプトはブール値を返す必要があります。true または false

ノート

カスタムパラメータ

filters のように、スクリプトはより速い実行のためにキャッシュされます。スクリプトの引数を頻繁に変更する場合は、スクリプトの params パラメータに保存することをお勧めします。例えば:

Python

  1. resp = client.search(
  2. query={
  3. "bool": {
  4. "filter": {
  5. "script": {
  6. "script": {
  7. "source": "doc['num1'].value > params.param1",
  8. "lang": "painless",
  9. "params": {
  10. "param1": 5
  11. }
  12. }
  13. }
  14. }
  15. }
  16. },
  17. )
  18. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. query: {
  4. bool: {
  5. filter: {
  6. script: {
  7. script: {
  8. source: "doc['num1'].value > params.param1",
  9. lang: 'painless',
  10. params: {
  11. "param1": 5
  12. }
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }
  19. )
  20. puts response

Js

  1. const response = await client.search({
  2. query: {
  3. bool: {
  4. filter: {
  5. script: {
  6. script: {
  7. source: "doc['num1'].value > params.param1",
  8. lang: "painless",
  9. params: {
  10. param1: 5,
  11. },
  12. },
  13. },
  14. },
  15. },
  16. },
  17. });
  18. console.log(response);

コンソール

  1. GET /_search
  2. {
  3. "query": {
  4. "bool": {
  5. "filter": {
  6. "script": {
  7. "script": {
  8. "source": "doc['num1'].value > params.param1",
  9. "lang": "painless",
  10. "params": {
  11. "param1": 5
  12. }
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }

高コストのクエリを許可する

search.allow_expensive_queries が false に設定されている場合、スクリプトクエリは実行されません。