Elasticsearch соответствует полному набору терминов - PullRequest
3 голосов
/ 09 января 2020

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

Пример:

 filter:
   id: ["a", "b"]

 documents:  
   id: ["a", "b"] -> match  
   id: ["b", "a"] -> match  
   id: ["a"] -> no match  
   id: ["a", "b", "c"] -> no match  

В конечном счете, я хочу использовать Java REST-клиент высокого уровня для реализации запроса, хотя пример дляasticsearch dsl подойдет а также.

Ответы [ 2 ]

2 голосов
/ 14 января 2020

Я хотел бы предложить что-то, что помешает вам поддерживать длинную цепочку обязательных условий, как только ваши требования изменятся (например, представьте, что у вас есть набор из шести элементов для соответствия). Я собираюсь положиться на запрос сценария, который может выглядеть чрезмерно сложным, но из него будет легко создать шаблон поиска (https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-template.html).

{
"query": {
    "bool": {
      "filter": {
        "script": {
          "script": {
            "source": """
              def ids = new ArrayList(doc['id.keyword']);
              def param = new ArrayList(params.terms);
              def isSameSize = ids.size() == param.size();
              def isSameContent = ids.containsAll(param);
              return isSameSize && isSameContent
            """,
            "lang": "painless",
            "params": {
              "terms": [ "a", "b" ]
            }
          }
        }
      }
    }
  }
}

Таким образом, единственное, что вам нужно будет изменить, это значение параметра terms.

1 голос
/ 13 января 2020

Хотя это, по-видимому, не поддерживается изначально, вы могли бы go опередить и использовать фильтр сценариев для достижения такого поведения следующим образом:

GET your_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "script": {
            "script": "doc['tags'].values.length == 2"
          }
        },
        {
          "term": {
            "tags": {
              "value": "a"
            }
          }
        },
        {
          "term": {
            "tags": {
              "value": "b"
            }
          }
        }
      ]
    }
  }
}

Фильтр сценариев ограничивает результат поиска размером массива в то время как термин фильтры определяет значения этого массива. Обязательно включите fielddata для тегов field для выполнения сценариев для него.

...