Поиск шаблона в Elastic для фильтра и должен - PullRequest
0 голосов
/ 08 октября 2019

Я настраиваю шаблон поиска, чтобы получить список фильтров bool в запросе bool. У меня есть 3 поля на es [A, B, C]. Запрос должен возвращать комбинации из этих трех полей. я должен быть в состоянии дать [a1, b1, c1] [a2, b2, c2] ... [an, bn, cn] в качестве параметров шаблона

Я попытался создать шаблон, который должензапрос с {{#toJson}} предложениями {{/ toJson}} для создания объектов внутреннего терма-фильтра, таких как

"clauses":[
{"term": {"fieldA": 30}},
{"term": {"fieldB": 0}},
{"term": {"fieldC": 1}}
]

Я надеялся, что вокруг него будет раздел внутри "should": [{{#shouldBlock}}{{#toJson}}clauses{{/toJson}}{{/ShouldBlock}}]

есть ли способ создать фильтр внутри фильтра, который принимает " toJson "

Как

"bool":{
"should":[
{
          // this loops for 100 times   
          "bool":{
                  "filter":[
                          {term for fieldA},
                          {term for fieldB},  // three terms for three fields
                          {term for fieldC}
                           ] 
                 }
          // end of loop
}
]

Это мойзапрос. и это ожидается в качестве ответа для рендера

GET adn/_search
{
  "size": 10,
  "query": {
       "bool": {
         "minimum_should_match": 1, 
         "should": [
           {
             "bool": {
               "filter": [
                 {"term": {"fieldA": 30}},
                 {"term": {"fieldB": 0}},
                 {"term": {"fieldC": 1}}
               ]
           }
          },
            {
             "bool": {
               "filter": [
                 {"term": {"fieldA": 0}},
                 {"term": {"fieldB": 1}},
                 {"term": {"fieldC": 0}}
               ]
           }
          }
         ]
       }
     }
}

Моя первая попытка состояла в том, чтобы добавить внутреннее условие для if в виде текста внутри раздела

GET _render/template
{
    "source": "{\"query\": {\"bool\": {\"should\":[ {{#section}} {\"bool\":{\"filter\": {{#toJson}}clauses{{/toJson}} } } {{/section}} }}}",
    "params": {
      "section":{
        "shouldBlock":[]
      },
      "clauses": [
            { "term": { "breakId" : 1 } },
            { "term": { "offset" : 0 } }
        ]

    }
}

, который выдал ошибку

{
  "error": {
    "root_cause": [
      {
        "type": "json_parse_exception",
        "reason": "Unexpected close marker '}': expected ']' (for Array starting at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@5a909404; line: 1, column: 30])\n at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@5a909404; line: 1, column: 102]"
      }
    ],
    "type": "json_parse_exception",
    "reason": "Unexpected close marker '}': expected ']' (for Array starting at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@5a909404; line: 1, column: 30])\n at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@5a909404; line: 1, column: 102]"
  },
  "status": 500
}

Я пробовал что-то вроде раздела с параметром для хранения

GET _render/template
{
    "source": "{\"query\": {\"bool\": {\"should\":[ {{#section}} {{shouldBlock}} {{#toJson}}clauses{{/toJson}} }] {{/section}} } } }",
    "params": {
      "clauses": [
            { "term": { "fieldA" : 1 } },
            { "term": { "fieldB" : 0 } }
        ]

    }
}

Вещи, которые я должен был иметь в виду. секция, которая повторяется: 100 раз

"bool":{
       "filter":[
                 {"term": {"fieldA": a1}},
                 {"term": {"fieldB": b1}},
                 {"term": {"fieldC": c1}},
                ]
}

Каждый объект из вышеуказанных 100 имеет отдельный блок фильтра с комбинацией 3 полей с разными значениями для этих 3 полей [fieldA, fieldB, fieldC]

Я читал, что массив для «фильтра» может быть получен с помощью функции упругого поиска «toJson», но мне трудно расшифровать его внешнюю часть

Было бы здорово, если бы кто-то мог мне помочьиз

1 Ответ

1 голос
/ 08 октября 2019

Ваш запрос не верный. Как только вы исправите, что это должно работать:

render template

Вот тот, который работает:

GET _render/template
{
  "source": """{
  "query": {
    "bool": {
      {{#section}}
      "should": [
        {
          "bool": {
            "filter": [
              {{#toJson}}clauses{{/toJson}}
              ]
          }
        }
      ]
      {{/section}}
    }
  }
}""",
  "params": {
    "section":true, 
    "clauses": [
      {
        "term": {
          "fieldA": 1
        }
      },
      {
        "term": {
          "fieldB": 0
        }
      }
    ]
  }
}

Редактировать на основекомментарий:


Все ваши запросы будут тогда частью параметров запроса. усы - это шаблоны без логики, поэтому вы не можете иметь if-else или loops

GET _render/template
{
  "source": """
{
  "query": {
    "bool": {
      {{#section}}
      "should": {{#toJson}}clauses{{/toJson}}
      {{/section}}
    }
  }
}
""",
  "params": {
  "section":true,
    "clauses": [
      {
        "bool": {
          "filter": [
            {
              "term": {
                "fieldA": 1
              }
            },
            {
              "term": {
                "fieldB": 0
              }
            }
          ]
        }
      },
        {
          "bool": {
          "filter": [
            {
              "term": {
                "fieldA": 1
              }
            },
            {
              "term": {
                "fieldB": 0
              }
            }
          ]
        }
        },
        {
          "bool": {
          "filter": [
            {
              "term": {
                "fieldA": 1
              }
            },
            {
              "term": {
                "fieldB": 0
              }
            }
          ]
        }
        }

    ]
  }
}
...