语义文本字段类型

编辑

此功能为 Beta 版,可能会发生变更。其设计和代码不如正式 GA 功能成熟,因此按现状提供,不提供任何担保。Beta 版功能不受正式 GA 功能的支持 SLA 约束。

semantic_text 字段类型使用推理端点自动为文本内容生成嵌入向量。长段落会自动分块为较小的部分,以便处理更大的文本语料库。

semantic_text 字段类型指定用于生成嵌入向量的推理端点标识符。您可以使用创建推理 API 创建推理端点。此字段类型和semantic 查询类型使您可以更轻松地对数据执行语义搜索。

如果未指定推理端点,则 inference_id 字段默认为 .elser-2-elasticsearch,这是 Elasticsearch 服务的一个预配置端点。

使用 semantic_text,您无需指定如何为数据生成嵌入向量,或如何索引数据。推理端点会自动确定要使用的嵌入向量生成、索引和查询。

如果使用预配置的 .elser-2-elasticsearch 端点,则可以使用以下 API 请求设置 semantic_text

const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      inference_field: {
        type: "semantic_text",
      },
    },
  },
});
console.log(response);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "inference_field": {
        "type": "semantic_text"
      }
    }
  }
}

要使用自定义推理端点而不是默认的 .elser-2-elasticsearch,您必须创建推理 API,并在设置 semantic_text 字段类型时指定其 inference_id

const response = await client.indices.create({
  index: "my-index-000002",
  mappings: {
    properties: {
      inference_field: {
        type: "semantic_text",
        inference_id: "my-openai-endpoint",
      },
    },
  },
});
console.log(response);
PUT my-index-000002
{
  "mappings": {
    "properties": {
      "inference_field": {
        "type": "semantic_text",
        "inference_id": "my-openai-endpoint" 
      }
    }
  }
}

用于生成嵌入向量的推理端点的 inference_id

使用 semantic_text 的推荐方法是为摄取和搜索设置专用的推理端点。这可确保搜索速度不受摄取工作负载的影响,反之亦然。为两者创建专用推理端点后,您可以在为使用 semantic_text 字段的索引设置索引映射时,使用 inference_idsearch_inference_id 参数引用它们。

const response = await client.indices.create({
  index: "my-index-000003",
  mappings: {
    properties: {
      inference_field: {
        type: "semantic_text",
        inference_id: "my-elser-endpoint-for-ingest",
        search_inference_id: "my-elser-endpoint-for-search",
      },
    },
  },
});
console.log(response);
PUT my-index-000003
{
  "mappings": {
    "properties": {
      "inference_field": {
        "type": "semantic_text",
        "inference_id": "my-elser-endpoint-for-ingest",
        "search_inference_id": "my-elser-endpoint-for-search"
      }
    }
  }
}

semantic_text 字段的参数

编辑
inference_id
(必需,字符串)将用于为字段生成嵌入向量的推理端点。默认情况下,使用 .elser-2-elasticsearch。此参数无法更新。使用创建推理 API 创建端点。如果指定了 search_inference_id,则推理端点仅在索引时使用。
search_inference_id
(可选,字符串)将用于在查询时生成嵌入向量的推理端点。您可以使用更新映射 API 更新此参数。使用创建推理 API 创建端点。如果未指定,则 inference_id 定义的推理端点将在索引和查询时使用。

推理端点验证

编辑

创建映射时不会验证 inference_id,而是在将文档摄取到索引中时进行验证。当第一个文档被索引时,inference_id 将用于为字段生成底层索引结构。

删除推理端点会导致使用该推理端点作为其 inference_id 定义 semantic_text 字段的索引上的文档摄取和语义查询失败。尝试删除在 semantic_text 字段上使用的推理端点会导致错误。

文本分块

编辑

推理端点可以处理的文本量有限制。为了允许在语义搜索中使用大量文本,semantic_text 会在需要时自动生成较小的段落,称为分块

每个分块将包含文本子段以及从中生成的相应嵌入向量。查询时,将自动搜索每个文档的各个段落,并使用最相关的段落计算分数。

有关分块以及如何配置分块设置的更多详细信息,请参阅推理 API 文档中的配置分块

semantic_text 结构

编辑

一旦摄取文档,semantic_text 字段将具有以下结构

"inference_field": {
  "text": "these are not the droids you're looking for", 
  "inference": {
    "inference_id": "my-elser-endpoint", 
    "model_settings": { 
      "task_type": "sparse_embedding"
    },
    "chunks": [ 
      {
        "text": "these are not the droids you're looking for",
        "embeddings": {
          (...)
        }
      }
    ]
  }
}

该字段将变为对象结构,以容纳原始文本和推理结果。

用于生成嵌入向量的 inference_id

模型设置,包括任务类型以及维度/相似度(如果适用)。

推理结果将按分块分组,每个分块都有其相应的文本和嵌入向量。

请参阅本教程,了解有关使用 semantic_textsemantic 查询进行语义搜索的更多信息。

自定义 semantic_text 索引

编辑

semantic_text 使用默认值,基于指定的推理端点索引数据。它通过提供自动推理和专用查询,使您可以快速开始语义搜索,而无需提供更多详细信息。

如果您想自定义数据索引,请使用sparse_vectordense_vector 字段类型,并使用推理处理器创建摄取管道以生成嵌入向量。本教程将指导您完成此过程。在这些情况下 - 当您使用 sparse_vectordense_vector 字段类型而不是 semantic_text 字段类型来自定义索引时 - semantic_query 不支持用于查询字段数据。

更新到 semantic_text 字段

编辑

包含 semantic_text 字段的索引不支持使用脚本的更新。即使脚本以非 semantic_text 字段为目标,当索引包含 semantic_text 字段时,更新也会失败。

copy_to 支持

编辑

semantic_text 字段类型可以作为copy_to 字段的目标。这意味着您可以使用单个 semantic_text 字段来收集其他字段的值以进行语义搜索。每个值都会单独计算其嵌入向量;每个字段值都是生成的嵌入向量中的一组单独的分块。

这对使用 semantic_text 字段更新文档的批量请求和摄取管道施加了限制。在这些情况下,所有复制到 semantic_text 字段的字段(包括 semantic_text 字段值)都必须具有一个值,以确保正确计算每个嵌入向量。

例如,以下映射

const response = await client.indices.create({
  index: "test-index",
  mappings: {
    properties: {
      infer_field: {
        type: "semantic_text",
        inference_id: ".elser-2-elasticsearch",
      },
      source_field: {
        type: "text",
        copy_to: "infer_field",
      },
    },
  },
});
console.log(response);
PUT test-index
{
    "mappings": {
        "properties": {
            "infer_field": {
                "type": "semantic_text",
                "inference_id": ".elser-2-elasticsearch"
            },
            "source_field": {
                "type": "text",
                "copy_to": "infer_field"
            }
        }
    }
}

需要以下批量更新请求以确保正确更新 infer_field

resp = client.bulk(
    index="test-index",
    operations=[
        {
            "update": {
                "_id": "1"
            }
        },
        {
            "doc": {
                "infer_field": "updated inference field",
                "source_field": "updated source field"
            }
        }
    ],
)
print(resp)
const response = await client.bulk({
  index: "test-index",
  operations: [
    {
      update: {
        _id: "1",
      },
    },
    {
      doc: {
        infer_field: "updated inference field",
        source_field: "updated source field",
      },
    },
  ],
});
console.log(response);
PUT test-index/_bulk
{"update": {"_id": "1"}}
{"doc": {"infer_field": "updated inference field", "source_field": "updated source field"}}

请注意,semantic_text 字段和源字段都在批量请求中更新。

限制

编辑

semantic_text 字段类型有以下限制

  • semantic_text 字段目前不支持作为嵌套字段的元素。
  • semantic_text 字段目前无法设置为动态模板的一部分。
  • semantic_text 字段不能定义为另一个字段的多字段,也不能包含其他字段作为多字段。