Elasticsearch Java High Level Rest Client, создающий логический запрос с несколькими значениями соответствия и условием ИЛИ - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь построить запрос через клиент высокого уровня отдыха Java, который реализует получение списка идентификаторов и возвращение всех тех документов, которые соответствуют заданному идентификатору, аналогично предложению WHERE с оператором OR.

По этой причине я выполняю запрос bool и пытаюсь выполнить итерацию списка и должен соответствовать каждому значению с оператором, установленным в OR

BoolQueryBuilder builder = QueryBuilders.boolQuery();
ids.forEach(i -> {
     bool.must(QueryBuilders.matchQuery("_id", i).operator(Operator.OR));
});

return bool;

// это создает dsl таким образом

{
  "bool" : {
    "must" : [
      {
        "match" : {
          "_id" : {
            "query" : "0025370c-baea-4dcc-af48-56c4bdb86854",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      },
      {
        "match" : {
          "_id" : {
            "query" : "013fedef-6b04-4520-8458-fca8b0366833",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      },
      {
        "match" : {
          "_id" : {
            "query" : "01c44ce4-0e87-4dc9-8a29-1f24679d335f",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

, который сконструирован нормально, только он не работает, потому что я думаю, что OR вложено в low и не применяется к нескольким совпадениям. Поэтому я предполагаю, что должен быть вложенный тип, и я попробовал это:

BoolQueryBuilder bool = QueryBuilders.boolQuery();
BoolQueryBuilder subBool = QueryBuilders.boolQuery();
ids.forEach(i -> {
     subBool.must(QueryBuilders.matchQuery("_id", i).operator(Operator.OR));
});

bool.must(subBool);

return bool;

// для меня было бы более разумно поместить условие оператора в bool вместо subBool, но оно недоступно иЯ уверен, что я ошибаюсь

{
  "bool" : {
    "must" : [
      {
        "bool" : {
          "must" : [
            {
              "match" : {
                "_id" : {
                  "query" : "0025370c-baea-4dcc-af48-56c4bdb86854",
                  "operator" : "OR",
                  "prefix_length" : 0,
                  "max_expansions" : 50,
                  "fuzzy_transpositions" : true,
                  "lenient" : false,
                  "zero_terms_query" : "NONE",
                  "auto_generate_synonyms_phrase_query" : true,
                  "boost" : 1.0
                }
              }
            },
            {
              "match" : {
                "_id" : {
                  "query" : "013fedef-6b04-4520-8458-fca8b0366833",
                  "operator" : "OR",
                  "prefix_length" : 0,
                  "max_expansions" : 50,
                  "fuzzy_transpositions" : true,
                  "lenient" : false,
                  "zero_terms_query" : "NONE",
                  "auto_generate_synonyms_phrase_query" : true,
                  "boost" : 1.0
                }
              }
            },
            {
              "match" : {
                "_id" : {
                  "query" : "01c44ce4-0e87-4dc9-8a29-1f24679d335f",
                  "operator" : "OR",
                  "prefix_length" : 0,
                  "max_expansions" : 50,
                  "fuzzy_transpositions" : true,
                  "lenient" : false,
                  "zero_terms_query" : "NONE",
                  "auto_generate_synonyms_phrase_query" : true,
                  "boost" : 1.0
                }
              }
            }
          ],
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

Кажется, это сработает, если я уменьшу его до одного значения во вложенном совпадении (снова 1 идентификатор вместо лота) ... так что я все еще думаю, чтоЯ неправильно выполняю условие OR.

Фильтры в запросе bool вместо обязательных совпадений дают тот же результат. Ценю помощь.

1 Ответ

2 голосов
/ 17 октября 2019

Оператор OR в запросах match означает, что только один член каждой строки запроса этого конкретного подзапроса должен соответствовать документу, чтобы подзапрос соответствовал, так что это нек чему вы стремитесь. Чтобы составить подзапросы с OR, вы должны использовать should вместо must в своем корневом bool-запросе. must является ElasticSearch-эквивалентом AND -оператора, а should означает OR.

...