Elasticsearch Конвейерный поиск?

Я уже некоторое время использую Elasticsearch в своей компании и, похоже, до сих пор хорошо работал для наших поисков. Мы видели более сложные варианты использования от наших клиентов, которые нуждались в дополнительных «специальных/расширенных» возможностях запросов и связях между документами (или объединениях в традиционном смысле). Я понимаю, что ES не создан для объединений, и рекомендуемым способом является денормализация. До сих пор мы денормализовали документы для поддержки каждого варианта использования, и это само по себе стало слишком сложным и дорогим для нас, поскольку нашим клиентам приходится долго ждать, чтобы развернуть это изменение кода.

Наш бизнес чаще критиковал нас за то, что «Эй, ваша модель данных неверна. Она не подходит для более умных запросов». Команде каждый раз мучительно труднее объяснить, зачем нужна денормализация.

Несколько примеров проблем:

"Find me all the persons having the same birthdays"
"Find me all the persons travelling to the same cities within the same time frame"

Представьте себе, что каждый документ о событии — это запись о человеке с информацией о его путешествии.

Итак, существует ли концепция конвейерного поиска, в которой я могу разбить поиск на несколько поисковых запросов и передать результат одного в качестве ввода другому? Или есть какой-либо другой рекомендуемый способ решения таких проблем без необходимости кипятить океан?


person user1189332    schedule 09.10.2019    source источник
comment
Можете ли вы поделиться образцом документа с записью о человеке с данными о его поездке? Почти уверен, что два приведенных выше запроса можно просто решить с помощью агрегатов.   -  person Val    schedule 09.10.2019
comment
просто из любопытства, почему вы выбрали для этого подход nosql? кажется, что реляционная база данных подойдет   -  person lunadir    schedule 20.05.2021


Ответы (1)


Два приведенных выше запроса могут быть решены с помощью агрегатов.

Я предполагаю следующий образец документа/схемы:

{
  "firstName": "John",
  "lastName": "Doe",
  "birthDate": "1998-04-02",
  "travelDate": "2019-10-31",
  "city": "London"
}

Первый путем объединения с terms в поле даты рождения (день года) и min_doc_count: 2, например:

{
  "size": 0,
  "aggs": {
    "birthdays": {
      "terms": {
        "script": "return LocalDate.parse(params._source.birthDate).format(DateTimeFormatter.ofPattern('MM/dd'))",
        "min_doc_count": 2
      },
      "aggs": {
        "persons": {
          "top_hits": {}
        }
      }
    }
  }
}

Второй - путем агрегирования с terms агрегацией в поле city и ограничением с помощью range запроса в поле travelDate для желаемого периода времени:

{
  "size": 0,
  "query": {
    "range": {
      "travelDate": {
        "gte": "2019-10-01",
        "lt": "2019-11-01"
      }
    }
  },
  "aggs": {
    "cities": {
      "terms": {
        "field": "city.keyword"
      },
      "aggs": {
        "persons": {
          "top_hits": {}
        }
      }
    }
  }
}

Второй запрос также можно выполнить с помощью свертывание поля:

{
  "_source": false,
  "query": {
    "range": {
      "travelDate": {
        "gte": "2019-10-01",
        "lt": "2019-11-01"
      }
    }
  },
  "collapse": {
    "field": "city.keyword",
    "inner_hits": {
      "name": "people"
    }
  }
}

Если вам нужны обе агрегации одновременно, это определенно возможно сделать:

{
  "size": 0,
  "aggs": {
    "birthdays": {
      "terms": {
        "script": "return LocalDate.parse(params._source.birthDate).format(DateTimeFormatter.ofPattern('MM/dd'))",
        "min_doc_count": 2
      },
      "aggs": {
        "persons": {
          "top_hits": {}
        }
      }
    },
    "travels": {
      "filter": {
        "range": {
          "travelDate": {
            "gte": "2019-10-01",
            "lt": "2019-11-01"
          }
        }
      },
      "aggs": {
        "cities": {
          "terms": {
            "field": "city.keyword"
          },
          "aggs": {
            "persons": {
              "top_hits": {}
            }
          }
        }
      }
    }
  }
}
person Val    schedule 09.10.2019
comment
Могу ли я И эти совершенно 2 разные агрегации? Должен ли я смотреть на вложенные агрегации терминов друг в друга или составные агрегации? - person user1189332; 09.10.2019
comment
Ура, рад, что помогло! - person Val; 16.10.2019