Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Руководство [8.17] ›DSL запросов ›Запросы на основе векторов

Запрос расширения текста

Устаревший в 8.15.0.

Этот запрос заменён запросом разреженного вектора.

Примечание об устаревании

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

Запрос расширения текста использует модель обработки естественного языка для преобразования текста запроса в список пар «токен-вес», которые затем используются в запросе к полю разреженного вектора или ранжирования признаков.

Пример запроса

resp = client.search(
    query={
        "text_expansion": {
            "<sparse_vector_field>": {
                "model_id": "the model to produce the token weights",
                "model_text": "the query string"
            }
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      text_expansion: {
        "<sparse_vector_field>": {
          model_id: 'the model to produce the token weights',
          model_text: 'the query string'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  query: {
    text_expansion: {
      "<sparse_vector_field>": {
        model_id: "the model to produce the token weights",
        model_text: "the query string",
      },
    },
  },
});
console.log(response);
GET _search
{
   "query":{
      "text_expansion":{
         "<sparse_vector_field>":{
            "model_id":"the model to produce the token weights",
            "model_text":"the query string"
         }
      }
   }
}

Параметры верхнего уровня для text_expansion

<sparse_vector_field>
(Обязательно, объект) Название поля, содержащего пары «токен-вес», созданные моделью обработки естественного языка на основе входного текста.

Параметры верхнего уровня для <sparse_vector_field>

model_id
(Обязательно, строка) Идентификатор модели, используемой для преобразования текста запроса в пары «токен-вес». Он должен совпадать с идентификатором модели, используемой для создания токенов из входного текста.
model_text
(Обязательно, строка) Текст запроса, используемый для поиска.
pruning_config

(Необязательно, объект) [превью] Эта функция находится на стадии технического превью и может быть изменена или удалена в будущих выпусках. Elastic будет работать над исправлением любых проблем, но функции в техническом превью не подпадают под SLA поддержки официальных функций GA. Необязательная конфигурация обрезки. Если включена, она опускает незначащие токены из запроса для повышения производительности запроса. По умолчанию: Выключено.

Параметры для <pruning_config>:

tokens_freq_ratio_threshold
(Необязательно, целое число) [превью] Эта функция находится на стадии технического превью и может быть изменена или удалена в будущих выпусках. Elastic будет работать над исправлением любых проблем, но функции в техническом превью не подпадают под SLA поддержки официальных функций GA. Токены, частота которых превышает tokens_freq_ratio_threshold раз среднюю частоту всех токенов в указанном поле, считаются выбросами и обрезаются. Это значение должно быть от 1 до 100. По умолчанию: 5.
tokens_weight_threshold
(Необязательно, дробное число) [превью] Эта функция находится на стадии технического превью и может быть изменена или удалена в будущих выпусках. Elastic будет работать над исправлением любых проблем, но функции в техническом превью не подпадают под SLA поддержки официальных функций GA. Токены, вес которых меньше tokens_weight_threshold, считаются незначительными и обрезаются. Это значение должно быть от 0 до 1. По умолчанию: 0.4.
only_score_pruned_tokens
(Необязательно, логическое значение) [превью] Эта функция находится на стадии технического превью и может быть изменена или удалена в будущих выпусках. Elastic будет работать над исправлением любых проблем, но функции в техническом превью не подпадают под SLA поддержки официальных функций GA. Если true, мы вводим только обрезные токены в подсчёт, а незначащие токены отбрасываются. Сильно рекомендуется установить это значение в false для основного запроса, но это значение может быть установлено в true для запроса ререйтинга, чтобы получить более релевантные результаты. По умолчанию: false.

Значения по умолчанию для tokens_freq_ratio_threshold и tokens_weight_threshold были выбраны на основе тестов с использованием ELSER, которые обеспечили наиболее оптимальные результаты.

Пример запроса ELSER

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

resp = client.search(
    index="my-index",
    query={
        "text_expansion": {
            "ml.tokens": {
                "model_id": ".elser_model_2",
                "model_text": "How is the weather in Jamaica?"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index',
  body: {
    query: {
      text_expansion: {
        'ml.tokens' => {
          model_id: '.elser_model_2',
          model_text: 'How is the weather in Jamaica?'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index",
  query: {
    text_expansion: {
      "ml.tokens": {
        model_id: ".elser_model_2",
        model_text: "How is the weather in Jamaica?",
      },
    },
  },
});
console.log(response);
GET my-index/_search
{
   "query":{
      "text_expansion":{
         "ml.tokens":{
            "model_id":".elser_model_2",
            "model_text":"How is the weather in Jamaica?"
         }
      }
   }
}

Несколько запросов text_expansion могут быть объединены друг с другом или с другими типами запросов. Это можно сделать, обернув их в положения булевых запросов и используя линейное усиление:

resp = client.search(
    index="my-index",
    query={
        "bool": {
            "should": [
                {
                    "text_expansion": {
                        "ml.inference.title_expanded.predicted_value": {
                            "model_id": ".elser_model_2",
                            "model_text": "How is the weather in Jamaica?",
                            "boost": 1
                        }
                    }
                },
                {
                    "text_expansion": {
                        "ml.inference.description_expanded.predicted_value": {
                            "model_id": ".elser_model_2",
                            "model_text": "How is the weather in Jamaica?",
                            "boost": 1
                        }
                    }
                },
                {
                    "multi_match": {
                        "query": "How is the weather in Jamaica?",
                        "fields": [
                            "title",
                            "description"
                        ],
                        "boost": 4
                    }
                }
            ]
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index',
  body: {
    query: {
      bool: {
        should: [
          {
            text_expansion: {
              'ml.inference.title_expanded.predicted_value' => {
                model_id: '.elser_model_2',
                model_text: 'How is the weather in Jamaica?',
                boost: 1
              }
            }
          },
          {
            text_expansion: {
              'ml.inference.description_expanded.predicted_value' => {
                model_id: '.elser_model_2',
                model_text: 'How is the weather in Jamaica?',
                boost: 1
              }
            }
          },
          {
            multi_match: {
              query: 'How is the weather in Jamaica?',
              fields: [
                'title',
                'description'
              ],
              boost: 4
            }
          }
        ]
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index",
  query: {
    bool: {
      should: [
        {
          text_expansion: {
            "ml.inference.title_expanded.predicted_value": {
              model_id: ".elser_model_2",
              model_text: "How is the weather in Jamaica?",
              boost: 1,
            },
          },
        },
        {
          text_expansion: {
            "ml.inference.description_expanded.predicted_value": {
              model_id: ".elser_model_2",
              model_text: "How is the weather in Jamaica?",
              boost: 1,
            },
          },
        },
        {
          multi_match: {
            query: "How is the weather in Jamaica?",
            fields: ["title", "description"],
            boost: 4,
          },
        },
      ],
    },
  },
});
console.log(response);
GET my-index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "text_expansion": {
            "ml.inference.title_expanded.predicted_value": {
              "model_id": ".elser_model_2",
              "model_text": "How is the weather in Jamaica?",
              "boost": 1
            }
          }
        },
        {
          "text_expansion": {
            "ml.inference.description_expanded.predicted_value": {
              "model_id": ".elser_model_2",
              "model_text": "How is the weather in Jamaica?",
              "boost": 1
            }
          }
        },
        {
          "multi_match": {
            "query": "How is the weather in Jamaica?",
            "fields": [
              "title",
              "description"
            ],
            "boost": 4
          }
        }
      ]
    }
  }
}

Это также можно сделать, используя взаимное ранжирование слияния (RRF), через поисковик с несколькими стандартными поисковиками.

resp = client.search(
    index="my-index",
    retriever={
        "rrf": {
            "retrievers": [
                {
                    "standard": {
                        "query": {
                            "multi_match": {
                                "query": "How is the weather in Jamaica?",
                                "fields": [
                                    "title",
                                    "description"
                                ]
                            }
                        }
                    }
                },
                {
                    "standard": {
                        "query": {
                            "text_expansion": {
                                "ml.inference.title_expanded.predicted_value": {
                                    "model_id": ".elser_model_2",
                                    "model_text": "How is the weather in Jamaica?"
                                }
                            }
                        }
                    }
                },
                {
                    "standard": {
                        "query": {
                            "text_expansion": {
                                "ml.inference.description_expanded.predicted_value": {
                                    "model_id": ".elser_model_2",
                                    "model_text": "How is the weather in Jamaica?"
                                }
                            }
                        }
                    }
                }
            ],
            "window_size": 10,
            "rank_constant": 20
        }
    },
)
print(resp)
const response = await client.search({
  index: "my-index",
  retriever: {
    rrf: {
      retrievers: [
        {
          standard: {
            query: {
              multi_match: {
                query: "How is the weather in Jamaica?",
                fields: ["title", "description"],
              },
            },
          },
        },
        {
          standard: {
            query: {
              text_expansion: {
                "ml.inference.title_expanded.predicted_value": {
                  model_id: ".elser_model_2",
                  model_text: "How is the weather in Jamaica?",
                },
              },
            },
          },
        },
        {
          standard: {
            query: {
              text_expansion: {
                "ml.inference.description_expanded.predicted_value": {
                  model_id: ".elser_model_2",
                  model_text: "How is the weather in Jamaica?",
                },
              },
            },
          },
        },
      ],
      window_size: 10,
      rank_constant: 20,
    },
  },
});
console.log(response);
GET my-index/_search
{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "How is the weather in Jamaica?",
                "fields": [
                  "title",
                  "description"
                ]
              }
            }
          }
        },
        {
          "standard": {
            "query": {
              "text_expansion": {
                "ml.inference.title_expanded.predicted_value": {
                  "model_id": ".elser_model_2",
                  "model_text": "How is the weather in Jamaica?"
                }
              }
            }
          }
        },
        {
          "standard": {
            "query": {
              "text_expansion": {
                "ml.inference.description_expanded.predicted_value": {
                  "model_id": ".elser_model_2",
                  "model_text": "How is the weather in Jamaica?"
                }
              }
            }
          }
        }
      ],
      "window_size": 10,
      "rank_constant": 20
    }
  }
}

Пример запроса ELSER с настройкой обрезки и ререйтингом

В приведенном ниже примере показано расширение предыдущего примера, добавляющее [превью] Эта функция находится на стадии технического превью и может быть изменена или удалена в будущих выпусках. Elastic будет работать над исправлением любых проблем, но функции в техническом превью не подпадают под SLA поддержки официальных функций GA. конфигурацию обрезки к запросу text_expansion. Конфигурация обрезки определяет незначащие токены для обрезки из запроса, чтобы улучшить производительность запроса.

Обрезка токенов происходит на уровне фрагмента. Хотя это должно привести к тому, что одинаковые токены будут помечены как незначащие во всех фрагментах, это не гарантируется на основе состава каждого фрагмента. Поэтому, если вы используете text_expansion с pruning_config на индексе с несколькими фрагментами, настоятельно рекомендуется добавить функцию ререйтинга отфильтрованных результатов поиска с токенами, которые изначально были обрезанными из запроса. Это поможет смягчить любые несоответствия на уровне фрагментов с обрезанными токенами и обеспечит лучшую релевантность в целом.

resp = client.search(
    index="my-index",
    query={
        "text_expansion": {
            "ml.tokens": {
                "model_id": ".elser_model_2",
                "model_text": "How is the weather in Jamaica?",
                "pruning_config": {
                    "tokens_freq_ratio_threshold": 5,
                    "tokens_weight_threshold": 0.4,
                    "only_score_pruned_tokens": False
                }
            }
        }
    },
    rescore={
        "window_size": 100,
        "query": {
            "rescore_query": {
                "text_expansion": {
                    "ml.tokens": {
                        "model_id": ".elser_model_2",
                        "model_text": "How is the weather in Jamaica?",
                        "pruning_config": {
                            "tokens_freq_ratio_threshold": 5,
                            "tokens_weight_threshold": 0.4,
                            "only_score_pruned_tokens": True
                        }
                    }
                }
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index',
  body: {
    query: {
      text_expansion: {
        'ml.tokens' => {
          model_id: '.elser_model_2',
          model_text: 'How is the weather in Jamaica?',
          pruning_config: {
            tokens_freq_ratio_threshold: 5,
            tokens_weight_threshold: 0.4,
            only_score_pruned_tokens: false
          }
        }
      }
    },
    rescore: {
      window_size: 100,
      query: {
        rescore_query: {
          text_expansion: {
            'ml.tokens' => {
              model_id: '.elser_model_2',
              model_text: 'How is the weather in Jamaica?',
              pruning_config: {
                tokens_freq_ratio_threshold: 5,
                tokens_weight_threshold: 0.4,
                only_score_pruned_tokens: true
              }
            }
          }
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index",
  query: {
    text_expansion: {
      "ml.tokens": {
        model_id: ".elser_model_2",
        model_text: "How is the weather in Jamaica?",
        pruning_config: {
          tokens_freq_ratio_threshold: 5,
          tokens_weight_threshold: 0.4,
          only_score_pruned_tokens: false,
        },
      },
    },
  },
  rescore: {
    window_size: 100,
    query: {
      rescore_query: {
        text_expansion: {
          "ml.tokens": {
            model_id: ".elser_model_2",
            model_text: "How is the weather in Jamaica?",
            pruning_config: {
              tokens_freq_ratio_threshold: 5,
              tokens_weight_threshold: 0.4,
              only_score_pruned_tokens: true,
            },
          },
        },
      },
    },
  },
});
console.log(response);
GET my-index/_search
{
   "query":{
      "text_expansion":{
         "ml.tokens":{
            "model_id":".elser_model_2",
            "model_text":"How is the weather in Jamaica?",
            "pruning_config": {
               "tokens_freq_ratio_threshold": 5,
               "tokens_weight_threshold": 0.4,
               "only_score_pruned_tokens": false
           }
         }
      }
   },
   "rescore": {
      "window_size": 100,
      "query": {
         "rescore_query": {
            "text_expansion": {
               "ml.tokens": {
                  "model_id": ".elser_model_2",
                  "model_text": "How is the weather in Jamaica?",
                  "pruning_config": {
                     "tokens_freq_ratio_threshold": 5,
                     "tokens_weight_threshold": 0.4,
                     "only_score_pruned_tokens": true
                  }
               }
            }
         }
      }
   }
}

В зависимости от ваших данных, запрос расширения текста может быть быстрее с помощью track_total_hits: false.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/query-dsl-text-expansion-query.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API