В elk существует возможность делать вложенный поиск, т.е искать по заданным критериям в уже выполненном поиске. Такой поиск также называется как bool query.

Включает в себя 4 оператора:

  1. must
  2. must_not
  3. should
  4. filter

Рассмотрим каждый из них подробнее чтобы понять в чем их различия.

must

Равнозначен and, т.е означает что введённое значение должно находится в выведенных документах. Чем больше must в условиях тем больше совпадений должно быть найдено.

Например выведем все документы со значением logstah в поле content и значением Engineering в category. Видим что их количество 91

GET blogs/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "logstah"
          }
        },
        {
          "match": {
            "category": "Engineering"
          }
        }
      ]
    }
  }
}

Например выведем все документы со значением logstah и access в поле content и значением Releases в category. Видим что их количество 21

GET blogs/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        },
        {
          "match": {
            "category": "Releases"
          }
        },
        {
          "match": {
            "content": "access"
          }
        }
      ]
    }
  }
}

must_not

Оператор must not означает что в результатах поиска не должно присутствовать переданное значение. В примере ищем поле content с присутствующим словом Elastic и category с отсутствующим значением News ( всё корме News ).

GET blogs/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
      , "must_not": [
        {"match": {
          "category": "News"
        }}
      ]
    }
  }
}

should

Should в отличии от первых двух не исключает никаких документов из вывода. Он просто сортирует вывод в зависимости от запроса.

Например выведем документы с полем content, в котором находится слово Elastic. В выводе видим первые документы имеют разных author.

GET blogs/_search
{
  "_source": {
    "includes": ["author","title"]
  },
  "query": {
    
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
    }
  }
}

Например выведем документы с полем content, в котором находится слово Elastic и полем author используя should. В выводе видим первые документы имеют author которого мы указали в поиске Amy White.

GET blogs/_search
{
  "_source": {
    "includes": ["author","title"]
  },
  "query": {
    
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
      , "should": [
        {"match_phrase": {
            "author": "Amy White"
          }
        }
      ]
    }
  }
}

Для should можно задать параметр minimum_should_match, который задаёт количество совпадений при многоразовым should ( по умолчанию 0 для многоразовым should и 1 для одного should ). Если его выставить, то уже будет фильтрация документов.

GET blogs/_search
{
  "_source": {
    "includes": ["author","title"]
  },
  "query": {
    
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
      , "should": [
        {"match": { "title": "stack" }},
        {"match": { "title": "query" }},
        {"match": { "title": "speed" }}
      ]
    }
  }
}
GET blogs/_search
{
  "_source": {
    "includes": ["author","title"]
  },
  "query": {
    
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
      , "should": [
        {"match": { "title": "stack" }},
        {"match": { "title": "query" }},
        {"match": { "title": "speed" }}
      ],
      "minimum_should_match": 1
    }
  }
}

filter

Filter также исключает документы из вывода и в общем отвечает на вопрос да или нет. Т.е допустим вы хотите получить документы находящиеся в интервале какого-то времени. Соответственно вы задаёте данный интервал и если интервал совпадает ( ответ ДА ), то документ будет выведен.

Например выведем все документы со значением Elastic в поле content. Видим что их количество 716.

GET blogs/_search
{
  "_source": {
    "includes": ["author","title","publish_date"]
  },
  "query": {
    
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
    }
  }
}

Например выведем все документы со значением Elastic в поле content и дата публикации publish_date позднее чем 2017-05-24. Видим что их количество 166.

GET blogs/_search
{
  "_source": {
    "includes": ["author","title","publish_date"]
  },
  "query": {
    
    "bool": {
      "must": [
        {
          "match": {
            "content": "Elastic"
          }
        }
      ]
      , "filter": [
        {"range": {
          "publish_date": {
            "lte": "2017-05-24"
          }
        }}
      ]
    }
  }
}

Итоговая таблица что на что влияет

оператор влияет на hits влияет на _score фильтрует вывод
must Y Y N
must_not Y N Y
should N Y N
filter Y N Y