Параметр скрипта Elasticsearch содержит все со значением из документа - PullRequest
1 голос
/ 28 апреля 2020

Я пытаюсь использовать запрос сценария эластичного поиска с использованием Java SDK, чтобы определить, содержит ли коллекция идентификаторов, переданных в качестве параметра, все значения в проиндексированном документе.

Вот простой Например, не работает, я ожидаю, что это будет соответствовать документу, но это не так.

Поле документа attributes представляет собой массив с одним элементом [2]

BoolQueryBuilder qb = boolQuery();

Map<String, Object> params = new HashMap<String, Object>();
params.put( "list", Arrays.asList( 1L, 2L, 3L ) );

String expr = "params.list.containsAll(doc['attributes'])";

Script script = new Script( ScriptType.INLINE, "painless", expr, Collections.emptyMap(), params );

qb.should( scriptQuery( script ) );

Тем не менее, я пробовал эти различные жестко закодированные альтернативы, которые действительно работают

С жестко закодированным .contains(2) работает, как и ожидалось

BoolQueryBuilder qb = boolQuery();

Map<String, Object> params = new HashMap<String, Object>();
params.put( "list", Arrays.asList( 2L ) );

String expr = "params.list.contains(2)";

Script script = new Script( ScriptType.INLINE, "painless", expr, Collections.emptyMap(), params );

qb.should( scriptQuery( script ) );

С жестко закодированным .containsAll([2]) работает как положено

BoolQueryBuilder qb = boolQuery();

Map<String, Object> params = new HashMap<String, Object>();
params.put( "list", Arrays.asList( 2L ) );

String expr = "params.list.containsAll([2])";

Script script = new Script( ScriptType.INLINE, "painless", expr, Collections.emptyMap(), params );

qb.should( scriptQuery( script ) );

1 Ответ

0 голосов
/ 28 апреля 2020

Должен привести элементы params.list перед вызовом containsAll:

{
  "query": {
    "bool": {
      "must": [
        {
          "script": {
            "script": {
              "inline": """
              params.list.stream()
                         .map(num -> (long) num)
                         .collect(Collectors.toList())
                         .containsAll(
                           doc['attributes'].stream()
                                            .collect(Collectors.toList()))""",
              "params": {
                "list": [
                  2
                ]
              }
            }
          }
        }
      ]
    }
  }
}

, предполагая, что ваше отображение действительно определило atributes как таковое:

{
  "mappings": {
    "properties": {
      "attributes": {
        "type": "long"
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...