Комбинируйте диапазон и подбирайте в Elasticsearch - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть документы в индексе Elasticsearch со следующей структурой:

{
  "title": 'Nutrtional facts',
  "begin_timestamp" : 1582686052,
  "end_timestamp" : 1582686093
}

{
  "title": 'Guitar facts',
  "begin_timestamp" : 1447991100,
  "end_timestamp" : 1447994100
}

{
  "title": 'Hair style facts',
  "begin_timestamp" : 1447991100,
  "end_timestamp" : 1447994100
}

{
  "title": 'Piano facts',
  "begin_timestamp" : 1554416211,
  "end_timestamp" : 1591308724
}

Я собираюсь получить документы, заголовок которых совпадает с facts и если начальная или конечная метка времени больше текущей дата и время.

title matches `facts` && begin_timestamp > CURRENT_DATE_TIME OR end_timestamp > CURRENT_DATE_TIME

Текущий запрос, который я выполняю, выглядит следующим образом:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "facts"
          }
        }
      ],
      "should": [
        {
          "range": {
            "begin_timestamp_for_search": {
              "gte": 1580853917
            }
          }
        },
        {
          "range": {
            "begin_timestamp_for_search": {
              "gte": 1580853917
            }
          }
        }
      ]
    }
  }
}

Однако он совпадает со всем, что соответствует facts, и возвращает все документы независимо от временные метки до или после текущей даты и времени. Я довольно новичок в ES, и мне интересно, как я мог бы написать запрос, чтобы единственные документы, которые возвращались, были:

{
  "title": 'Nutrtional facts',
  "begin_timestamp" : 1582686052,
  "end_timestamp" : 1582686093
}

{
  "title": 'Piano facts',
  "begin_timestamp" : 1570227141,
  "end_timestamp" : 1591308724
}

Ответы [ 3 ]

0 голосов
/ 05 февраля 2020
  1. Ваш запрос имеет несколько неправильных имен - например, begin_timestamp_for_search должно быть begin_timestamp в соответствии с вашими документами
  2. Вам необходимо установить для параметра minimum_should_match значение 1, чтобы требовать хотя бы одного should условие соответствует ( ссылка на Elasti c документация )

Следовательно, ваш запрос должен выглядеть примерно так:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "facts"
          }
        }
      ],
      "should": [
        {
          "range": {
            "begin_timestamp": {
              "gte": 1580853917
            }
          }
        },
        {
          "range": {
            "end_timestamp": {
              "gte": 1580853917
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}
0 голосов
/ 05 февраля 2020

В ваших фрагментах кода есть несколько мелких опечаток, и вам нужно заключить в should -предложение еще один bool -запрос, который вы добавляете / перемещаете в условие must.

Решение (проверено с помощью ES 7.5.x)

POST my_index/_bulk
{"index": {}}
{"title": "Nutrtional facts", "begin_timestamp": 1582686052, "end_timestamp": 1582686093}
{"index": {}}
{"title": "Guitar facts", "begin_timestamp": 1447991100, "end_timestamp": 1447994100}
{"index": {}}
{"title": "Hair style facts", "begin_timestamp": 1447991100, "end_timestamp": 1447994100}
{"index": {}}
{"title": "Piano facts", "begin_timestamp": 1554416211, "end_timestamp": 1591308724}


GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"title": "facts"}},
        {"bool": {
          "should": [
            {"range": {"begin_timestamp": {"gte": 1580853917}}},
            {"range": {"end_timestamp": {"gte": 1580853917}}}
          ]
        }}
      ]
    }
  }
}

Комментарий 1: Приведенный выше фрагмент кода исправляет опечатки в фрагментах кода:

  • с использованием разных имен полей в документах и ​​в запросе
  • , запрашивающих оба раза одно и то же begin_timestamp -поле

Комментарий 2: "minimum_should_match": 1 не требуется, так как это поведение по умолчанию bool -запроса, состоящего только из should -классов.

Тип : лучше всего смоделировать ваши метки времени как поля типа date. Это позволяет вам использовать математику даты (например, now в ваших запросах). Внутренне Elasticsearch будет хранить ваши даты как epoch_in_millis.

0 голосов
/ 05 февраля 2020
{
    "from": 0,
    "size": 200,
    "query": {
        "bool": {
            "filter": [
                {
                    "bool": {
                        "must": [
                            {
                                "bool": {
                                    "must": [
                                        {
                                            "wildcard": {
                                                "title": {
                                                    "wildcard": "*facts*",
                                                    "boost": 1
                                                }
                                            }
                                        },
                                        {
                                            "bool": {
                                                "should": [
                                                    {
                                                        "range": {
                                                            "begin_timestamp": {
                                                                "from": 1580853917,
                                                                "to": null,
                                                                "include_lower": false,
                                                                "include_upper": true,
                                                                "boost": 1
                                                            }
                                                        }
                                                    },
                                                    {
                                                        "range": {
                                                            "end_timestamp": {
                                                                "from": 1580853917,
                                                                "to": null,
                                                                "include_lower": false,
                                                                "include_upper": true,
                                                                "boost": 1
                                                            }
                                                        }
                                                    }
                                                ],
                                                "adjust_pure_negative": true,
                                                "boost": 1
                                            }
                                        }
                                    ],
                                    "adjust_pure_negative": true,
                                    "boost": 1
                                }
                            }
                        ],
                        "adjust_pure_negative": true,
                        "boost": 1
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...