Перколяция

Используйте запрос перколяции для поиска сохраненных запросов, которые соответствуют данному документу.

Используйте запрос перколяции для поиска сохраненных запросов, которые соответствуют данному документу. Эта операция является противоположностью обычного поиска: вместо того чтобы находить документы, соответствующие запросу, вы находите запросы, соответствующие документу. Запросы перколяции часто используются для оповещений, уведомлений и обратных поисковых случаев.

Основные моменты

  • Вы можете перколировать документ, предоставленный в строке, или извлечь существующий документ из индекса.
  • Документ и сохраненные запросы должны использовать одни и те же имена и типы полей.
  • Вы можете комбинировать перколяцию с фильтрацией и оценкой, чтобы создать сложные системы соответствия.
  • Запросы перколяции считаются дорогими запросами и будут выполняться только если настройка кластера search.allow_expensive_queries установлена в true (по умолчанию). Если эта настройка установлена в false, запросы перколяции будут отклонены.

Примеры использования

Запросы перколяции полезны в различных сценариях реального времени. Некоторые распространенные случаи использования включают:

  • Уведомления для электронной коммерции: Пользователи могут зарегистрировать интерес к продуктам, например, “Уведомите меня, когда новые ноутбуки Apple будут в наличии”. Когда новые документы о продуктах индексируются, система находит всех пользователей с соответствующими сохраненными запросами и отправляет уведомления.

  • Уведомления о вакансиях: Соискатели сохраняют запросы на основе предпочтительных должностей или местоположений, и новые вакансии сопоставляются с этими запросами для триггера уведомлений.

  • Системы безопасности и оповещения: Перколируйте входящие данные журналов или событий по сохраненным правилам или паттернам аномалий.

  • Фильтрация новостей: Сопоставляйте входящие статьи с сохраненными профилями тем, чтобы классифицировать или доставлять релевантный контент.

Как работает перколяция

Сохраненные запросы хранятся в специальном типе поля перколятора. Документы сравниваются со всеми сохраненными запросами. Каждый соответствующий запрос возвращается с его _id. Если включено выделение, также возвращаются совпадающие текстовые фрагменты. Если отправляется несколько документов, поле _percolator_document_slot отображает соответствующий документ.

Пример запроса перколяции

{
  "query": {
    "percolate": {
      "field": "query",
      "document": {
        "title": "Новый ноутбук Apple",
        "price": 1500,
        "availability": "в наличии"
      }
    }
  }
}

В этом примере запрос перколяции ищет сохраненные запросы, которые соответствуют документу о новом ноутбуке Apple.

Пример использования перколяции

Следующие примеры демонстрируют, как сохранять запросы перколяции и тестировать документы против них, используя различные методы.

Создание индекса для хранения сохраненных запросов

Сначала создайте индекс и настройте его маппинги с типом поля перколятора для хранения сохраненных запросов:

PUT /my_percolator_index
{
  "mappings": {
    "properties": {
      "query": {
        "type": "percolator"
      },
      "title": {
        "type": "text"
      }
    }
  }
}

Добавление запроса, соответствующего “apple” в поле title

Добавьте запрос, который соответствует слову “apple” в поле заголовка:

POST /my_percolator_index/_doc/1
{
  "query": {
    "match": {
      "title": "apple"
    }
  }
}

Добавление запроса, соответствующего “banana” в поле title

Добавьте запрос, который соответствует слову “banana” в поле заголовка:

POST /my_percolator_index/_doc/2
{
  "query": {
    "match": {
      "title": "banana"
    }
  }
}

Перколяция встроенного документа

Проверьте встроенный документ против сохраненных запросов:

POST /my_percolator_index/_search
{
  "query": {
    "percolate": {
      "field": "query",
      "document": {
        "title": "Fresh Apple Harvest"
      }
    }
  }
}

Ответ

Ответ предоставляет сохраненный запрос перколяции, который ищет документы, содержащие слово “apple” в поле заголовка, идентифицированный по _id: 1:

{
  ...
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.13076457,
    "hits": [
      {
        "_index": "my_percolator_index",
        "_id": "1",
        "_score": 0.13076457,
        "_source": {
          "query": {
            "match": {
              "title": "apple"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        }
      }
    ]
  }
}

Перколяция с несколькими документами

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

POST /my_percolator_index/_search
{
  "query": {
    "percolate": {
      "field": "query",
      "documents": [
        { "title": "Banana flavoured ice-cream" },
        { "title": "Apple pie recipe" },
        { "title": "Banana bread instructions" },
        { "title": "Cherry tart" }
      ]
    }
  }
}

Ответ

Поле _percolator_document_slot помогает вам идентифицировать каждый документ (по индексу), соответствующий каждому сохраненному запросу:

{
  ...
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.54726034,
    "hits": [
      {
        "_index": "my_percolator_index",
        "_id": "1",
        "_score": 0.54726034,
        "_source": {
          "query": {
            "match": {
              "title": "apple"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            1
          ]
        }
      },
      {
        "_index": "my_percolator_index",
        "_id": "2",
        "_score": 0.31506687,
        "_source": {
          "query": {
            "match": {
              "title": "banana"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0,
            2
          ]
        }
      }
    ]
  }
}

Перколяция существующего индексированного документа

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

Создание отдельного индекса для ваших документов

Создайте индекс для хранения документов:

PUT /products
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      }
    }
  }
}

Добавление документа

Добавьте документ:

POST /products/_doc/1
{
  "title": "Banana Smoothie Special"
}

Проверка соответствия сохраненных запросов индексированному документу

Проверьте, соответствуют ли сохраненные запросы индексированному документу:

POST /my_percolator_index/_search
{
  "query": {
    "percolate": {
      "field": "query",
      "index": "products",
      "id": "1"
    }
  }
}

Вы должны предоставить как индекс, так и идентификатор при использовании сохраненного документа.

Перколяция пакетов (несколько документов)

Вы можете проверить несколько документов в одном запросе:

POST /my_percolator_index/_search
{
  "query": {
    "percolate": {
      "field": "query",
      "documents": [
        { "title": "Apple event coming soon" },
        { "title": "Banana farms expand" },
        { "title": "Cherry season starts" }
      ]
    }
  }
}

Ответ

Каждое совпадение указывает на соответствующий документ в поле _percolator_document_slot:

{
  ...
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.46484798,
    "hits": [
      {
        "_index": "my_percolator_index",
        "_id": "2",
        "_score": 0.46484798,
        "_source": {
          "query": {
            "match": {
              "title": "banana"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            1
          ]
        }
      },
      {
        "_index": "my_percolator_index",
        "_id": "1",
        "_score": 0.41211313,
        "_source": {
          "query": {
            "match": {
              "title": "apple"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        }
      }
    ]
  }
}

Многоуровневая перколяция с использованием именованного запроса

Вы можете перколировать разные документы внутри именованного запроса:

GET /my_percolator_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "percolate": {
            "field": "query",
            "document": {
              "title": "Apple pie recipe"
            },
            "name": "apple_doc"
          }
        },
        {
          "percolate": {
            "field": "query",
            "document": {
              "title": "Banana bread instructions"
            },
            "name": "banana_doc"
          }
        }
      ]
    }
  }
}

Ответ

Параметр name добавляется к полю _percolator_document_slot, чтобы предоставить соответствующий запрос:

{
  ...
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.13076457,
    "hits": [
      {
        "_index": "my_percolator_index",
        "_id": "1",
        "_score": 0.13076457,
        "_source": {
          "query": {
            "match": {
              "title": "apple"
            }
          }
        },
        "fields": {
          "_percolator_document_slot_apple_doc": [
            0
          ]
        }
      },
      {
        "_index": "my_percolator_index",
        "_id": "2",
        "_score": 0.13076457,
        "_source": {
          "query": {
            "match": {
              "title": "banana"
            }
          }
        },
        "fields": {
          "_percolator_document_slot_banana_doc": [
            0
          ]
        }
      }
    ]
  }
}

Этот подход позволяет вам настраивать более индивидуальную логику запросов для отдельных документов. В следующем примере поле title запрашивается в первом документе, а поле description запрашивается во втором документе. Также предоставляется параметр boost:

GET /my_percolator_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "constant_score": {
            "filter": {
              "percolate": {
                "field": "query",
                "document": {
                  "title": "Apple pie recipe"
                },
                "name": "apple_doc"
              }
            },
            "boost": 1.0
          }
        },
        {
          "constant_score": {
            "filter": {
              "percolate": {
                "field": "query",
                "document": {
                  "description": "Banana bread with honey"
                },
                "name": "banana_doc"
              }
            },
            "boost": 3.0
          }
        }
      ]
    }
  }
}

Сравнение пакетной перколяции и именованной перколяции

Обе методы — пакетная перколяция (с использованием документов) и именованная перколяция (с использованием bool и name) — могут использоваться для перколяции нескольких документов, но они различаются по тому, как результаты маркируются, интерпретируются и контролируются. Они предоставляют функционально схожие результаты, но с важными структурными различиями, описанными в следующей таблице.

Характеристика Пакетная (документы) Именованная (bool + percolate + name)
Формат ввода Один клауз перколяции, массив документов Несколько клауз перколяции, по одному на документ
Прослеживаемость по документу По индексу слота (0, 1, …) По имени (apple_doc, banana_doc)
Поле ответа для слота совпадения _percolator_document_slot: [0] _percolator_document_slot_<name>: [0]
Префикс выделения 0_title, 1_title apple_doc_title, banana_doc_title
Индивидуальный контроль по документу Не поддерживается Можно настроить каждую клаузу
Поддержка увеличений и фильтров Нет Да (по каждой клаузе)
Производительность Лучше для больших партий Немного медленнее при большом количестве клауз
Случай использования Массовое соответствие, большие потоки событий Прослеживание по документам, тестирование, индивидуальный контроль

Подсветка совпадений

Запросы перколяции обрабатывают подсветку иначе, чем обычные запросы:

  • В обычном запросе документ хранится в индексе, и поисковый запрос используется для подсветки совпадающих терминов.
  • В запросе перколяции роли меняются: сохраненные запросы (в индексе перколятора) используются для подсветки документа.

Это означает, что документ, предоставленный в поле document или documents, является целью для подсветки, и запросы перколяции определяют, какие разделы будут подсвечены.

Подсветка одного документа

Этот пример использует ранее определенные запросы в my_percolator_index. Используйте следующий запрос для подсветки совпадений в поле заголовка:

POST /my_percolator_index/_search
{
  "query": {
    "percolate": {
      "field": "query",
      "document": {
        "title": "Apple banana smoothie"
      }
    }
  },
  "highlight": {
    "fields": {
      "title": {}
    }
  }
}

Ответ

Совпадения подсвечиваются в зависимости от соответствующего запроса:

{
  ...
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.13076457,
    "hits": [
      {
        "_index": "my_percolator_index",
        "_id": "1",
        "_score": 0.13076457,
        "_source": {
          "query": {
            "match": {
              "title": "apple"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        },
        "highlight": {
          "title": [
            "<em>Apple</em> banana smoothie"
          ]
        }
      },
      {
        "_index": "my_percolator_index",
        "_id": "2",
        "_score": 0.13076457,
        "_source": {
          "query": {
            "match": {
              "title": "banana"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        },
        "highlight": {
          "title": [
            "Apple <em>banana</em> smoothie"
          ]
        }
      }
    ]
  }
}

Подсветка нескольких документов

При перколяции нескольких документов с использованием массива documents каждому документу присваивается индекс слота. Ключи подсветки принимают следующую форму, где <slot> — это индекс документа в вашем массиве documents:

"<slot>_<fieldname>": [ ... ]

Используйте следующую команду для перколяции двух документов с подсветкой:

POST /my_percolator_index/_search
{
  "query": {
    "percolate": {
      "field": "query",
      "documents": [
        { "title": "Apple pie recipe" },
        { "title": "Banana smoothie ideas" }
      ]
    }
  },
  "highlight": {
    "fields": {
      "title": {}
    }
  }
}

Ответ

Ответ содержит поля подсветки с префиксами, соответствующими слотам документов, такими как 0_title и 1_title:

{
  ...
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.31506687,
    "hits": [
      {
        "_index": "my_percolator_index",
        "_id": "1",
        "_score": 0.31506687,
        "_source": {
          "query": {
            "match": {
              "title": "apple"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        },
        "highlight": {
          "0_title": [
            "<em>Apple</em> pie recipe"
          ]
        }
      },
      {
        "_index": "my_percolator_index",
        "_id": "2",
        "_score": 0.31506687,
        "_source": {
          "query": {
            "match": {
              "title": "banana"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            1
          ]
        },
        "highlight": {
          "1_title": [
            "<em>Banana</em> smoothie ideas"
          ]
	   }
      }
    ]
  }
}

Параметры запроса перколяции

Запрос перколяции поддерживает следующие параметры:

Параметр Обязательный/Необязательный Описание
field Обязательный Поле, содержащее сохраненные запросы перколяции.
document Необязательный Один встроенный документ для сопоставления с сохраненными запросами.
documents Необязательный Массив нескольких встроенных документов для сопоставления с сохраненными запросами.
index Необязательный Индекс, содержащий документ, с которым вы хотите сопоставить.
id Необязательный Идентификатор документа для извлечения из индекса.
routing Необязательный Значение маршрутизации, используемое при извлечении документа.
preference Необязательный Предпочтение для маршрутизации шардов при извлечении документа.
name Необязательный Имя, присвоенное клаузе перколяции. Полезно при использовании нескольких клауз перколяции в запросе bool.