Как написать запрос по крайней мере N-терминов вместе с фильтром и must_not в Elasticsearch? - PullRequest
0 голосов
/ 06 мая 2019

Я хочу сопоставить документы, удовлетворяющие всем приведенным ниже условиям:

  1. author == "tom"
  2. status! = "Удалено"
  3. не менее двух из f1-f4 полей соответствуют заданным значениям

(все поля keyword)

{"size":24,
"query":{
  "bool":{
    "filter":[{"term":{"author":{"value":"tom","boost":1.0}}}],
    "must_not":[{"term":{"status":{"value":"deleted","boost":1.0}}}],
    "should":[
      {"term":{"f1":{"value":"v1","boost":1.0}}},
      {"term":{"f2":{"value":"v2","boost":1.0}}},
      {"term":{"f3":{"value":"v3","boost":1.0}}},
      {"term":{"f4":{"value":"v4","boost":1.0}}}
      ],
      "minimum_should_match":"2",
      "boost":1.0
  }}
}

ОБНОВЛЕНИЕ И РЕЗЮМЕ

Запрос, который я публикую выше, на самом деле правильный, но мой поставщик es установил нестандартный подключаемый модуль с ошибкой, выполняющий «оптимизацию запросов», которая приводит к игнорированию всех «minimal_should_match».Если вы столкнулись с той же проблемой и не можете найти никакой подсказки, возможно, вам следует проверить, установлен ли у вас какой-либо подозрительный плагин

1 Ответ

1 голос
/ 06 мая 2019

Ваш запрос правильный, вам просто нужно убрать флаг "adjust_pure_negative" или изменить его на false.

Короче говоря, эластик будет "игнорировать" все ваши запросы и просто фильтровать, используя must_notв случае, если флаг установлен в true. источник

также вы можете удалить boost:1, поскольку значение по умолчанию равно 1, что делает его избыточным.

РЕДАКТИРОВАТЬ: мой тест

    await client.index({index: 'test', id: 5, type: 'test', body: {author: "george", status: "deleted", f1: "v1", f2: "v2"}});
    await client.index({index: 'test', id: 6, type: 'test', body: {author: "george", status: "x", f1: "v1",}});
    await client.index({index: 'test', id: 7, type: 'test', body: {author: "george", status: "u", f1: "v1", f2: "v2"}});
    await client.index({index: 'test', id: 8, type: 'test', body: {author: "george", status: "q", f1: "v1", f4: "v4"}});
    await client.index({index: 'test', id: 9, type: 'test', body: {author: "george", status: "1", f3: "v3"}});
    let x = await client.search({
        index: 'test',
        body:
            {"size":24,
                "query":{
                    "bool":{
                        "filter":[{"term":{"author":{"value":"george","boost":1.0}}}],
                        "must_not":[{"term":{"status":{"value":"deleted","boost":1.0}}}],
                        "must":[{
                            "bool":{
                                "should":[
                                    {"term":{"f1":{"value":"v1","boost":1.0}}},
                                    {"term":{"f2":{"value":"v2","boost":1.0}}},
                                    {"term":{"f3":{"value":"v3","boost":1.0}}},
                                    {"term":{"f4":{"value":"v4","boost":1.0}}}],
                                "minimum_should_match":"2",
                                "adjust_pure_negative":false,
                                "boost":1.0}}
                        ],
                        "adjust_pure_negative":false,
                        "boost":1.0}}},
    });

результаты: 2 совпадения, как и ожидалось:

[
  {
    "_index": "test",
    "_type": "test",
    "_id": "7",
    "_score": 0.5753642,
    "_source": {
      "author": "george",
      "status": "u",
      "f1": "v1",
      "f2": "v2"
    }
  },
  {
    "_index": "test",
    "_type": "test",
    "_id": "8",
    "_score": 0.47000366,
    "_source": {
      "author": "george",
      "status": "q",
      "f1": "v1",
      "f4": "v4"
    }
  }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...