词向量 API编辑

检索特定文档字段中词条的信息和统计数据。

response = client.termvectors(
  index: 'my-index-000001',
  id: 1
)
puts response
GET /my-index-000001/_termvectors/1

请求编辑

GET /<索引>/_termvectors/<_id>

先决条件编辑

  • 如果启用了 Elasticsearch 安全功能,则您必须对目标索引或索引别名具有 read 索引权限

描述编辑

您可以检索存储在索引中的文档或请求正文中传递的*人工*文档的词向量。

您可以通过 fields 参数指定您感兴趣的字段,或者将字段添加到请求正文中。

response = client.termvectors(
  index: 'my-index-000001',
  id: 1,
  fields: 'message'
)
puts response
GET /my-index-000001/_termvectors/1?fields=message

可以使用通配符指定字段,类似于 多匹配查询

默认情况下,词向量是实时的,而不是近实时。可以通过将 realtime 参数设置为 false 来更改此设置。

您可以请求三种类型的值:*词条信息*、*词条统计信息* 和 *字段统计信息*。默认情况下,将返回所有字段的所有词条信息和字段统计信息,但词条统计信息除外。

词条信息编辑

  • 字段中的词频(始终返回)
  • 词条位置 (positions : true)
  • 开始和结束偏移量 (offsets : true)
  • 词条有效负载 (payloads : true),以 base64 编码的字节表示

如果请求的信息未存储在索引中,则将在可能的情况下动态计算。此外,还可以为甚至不存在于索引中、而是由用户提供的文档计算词向量。

开始和结束偏移量假定使用 UTF-16 编码。如果您想使用这些偏移量来获取生成此标记的原始文本,则应确保要获取子字符串的字符串也使用 UTF-16 编码。

词条统计信息编辑

term_statistics 设置为 true(默认为 false)将返回

  • 总词频(词条在所有文档中出现的频率)
  • 文档频率(包含当前词条的文档数量)

默认情况下,不会返回这些值,因为词条统计信息可能会严重影响性能。

字段统计信息编辑

field_statistics 设置为 false(默认为 true)将省略

  • 文档计数(包含此字段的文档数量)
  • 文档频率总和(此字段中所有词条的文档频率总和)
  • 总词频总和(此字段中每个词条的总词频总和)

词条过滤编辑

使用参数 filter,还可以根据词条的 tf-idf 分数过滤返回的词条。这对于找出文档的良好特征向量很有用。此功能的工作方式类似于 More Like This 查询第二阶段。有关用法,请参见 示例 5

支持以下子参数

max_num_terms

每个字段必须返回的最大词条数。默认为 25

min_term_freq

忽略源文档中频率低于此值的词条。默认为 1

max_term_freq

忽略源文档中频率高于此值的词条。默认为无限制。

min_doc_freq

忽略至少未出现在这么多文档中的词条。默认为 1

max_doc_freq

忽略出现在超过这么多文档中的词条。默认为无限制。

min_word_length

将忽略低于此值的最小词条长度。默认为 0

max_word_length

将忽略高于此值的最大词条长度。默认为无限制 (0)。

行为编辑

词条和字段统计信息不准确。不考虑已删除的文档。仅检索请求的文档所在的碎片的信息。因此,词条和字段统计信息仅可用作相对度量,而绝对数字在此上下文中没有意义。默认情况下,当请求人工文档的词向量时,会随机选择一个碎片来获取统计信息。仅使用 routing 来命中特定碎片。

路径参数编辑

<索引>
(必填,字符串)包含文档的索引的名称。
<_id>
(可选,字符串)文档的唯一标识符。

查询参数编辑

fields

(可选,字符串)要包含在统计信息中的字段的逗号分隔列表或通配符表达式。

用作默认列表,除非在 completion_fieldsfielddata_fields 参数中提供了特定的字段列表。

field_statistics
(可选,布尔值)如果为 true,则响应包括文档计数、文档频率总和和总词频总和。默认为 true
<offsets>
(可选,布尔值)如果为 true,则响应包括词条偏移量。默认为 true
payloads
(可选,布尔值)如果为 true,则响应包括词条有效负载。默认为 true
positions
(可选,布尔值)如果为 true,则响应包括词条位置。默认为 true
preference
(可选,字符串)指定应在其上执行操作的节点或碎片。默认为随机。
routing
(可选,字符串)用于将操作路由到特定碎片的自定义值。
realtime
(可选,布尔值)如果为 true,则请求是实时的,而不是近实时的。默认为 true。请参阅 实时
term_statistics
(可选,布尔值)如果为 true,则响应包括词频和文档频率。默认为 false
version
(可选,布尔值)如果为 true,则返回文档版本作为命中的一部分。
version_type
(可选,枚举)特定版本类型:externalexternal_gte

示例编辑

返回存储的词向量编辑

首先,我们创建一个存储词向量、有效负载等的索引。

response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        text: {
          type: 'text',
          term_vector: 'with_positions_offsets_payloads',
          store: true,
          analyzer: 'fulltext_analyzer'
        },
        fullname: {
          type: 'text',
          term_vector: 'with_positions_offsets_payloads',
          analyzer: 'fulltext_analyzer'
        }
      }
    },
    settings: {
      index: {
        number_of_shards: 1,
        number_of_replicas: 0
      },
      analysis: {
        analyzer: {
          fulltext_analyzer: {
            type: 'custom',
            tokenizer: 'whitespace',
            filter: [
              'lowercase',
              'type_as_payload'
            ]
          }
        }
      }
    }
  }
)
puts response
PUT /my-index-000001
{ "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "term_vector": "with_positions_offsets_payloads",
        "store" : true,
        "analyzer" : "fulltext_analyzer"
       },
       "fullname": {
        "type": "text",
        "term_vector": "with_positions_offsets_payloads",
        "analyzer" : "fulltext_analyzer"
      }
    }
  },
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0
    },
    "analysis": {
      "analyzer": {
        "fulltext_analyzer": {
          "type": "custom",
          "tokenizer": "whitespace",
          "filter": [
            "lowercase",
            "type_as_payload"
          ]
        }
      }
    }
  }
}

其次,我们添加一些文档

response = client.index(
  index: 'my-index-000001',
  id: 1,
  body: {
    fullname: 'John Doe',
    text: 'test test test '
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 2,
  refresh: 'wait_for',
  body: {
    fullname: 'Jane Doe',
    text: 'Another test ...'
  }
)
puts response
PUT /my-index-000001/_doc/1
{
  "fullname" : "John Doe",
  "text" : "test test test "
}

PUT /my-index-000001/_doc/2?refresh=wait_for
{
  "fullname" : "Jane Doe",
  "text" : "Another test ..."
}

以下请求返回文档 1(John Doe)中字段 text 的所有信息和统计信息

response = client.termvectors(
  index: 'my-index-000001',
  id: 1,
  body: {
    fields: [
      'text'
    ],
    offsets: true,
    payloads: true,
    positions: true,
    term_statistics: true,
    field_statistics: true
  }
)
puts response
GET /my-index-000001/_termvectors/1
{
  "fields" : ["text"],
  "offsets" : true,
  "payloads" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}

响应

{
  "_index": "my-index-000001",
  "_id": "1",
  "_version": 1,
  "found": true,
  "took": 6,
  "term_vectors": {
    "text": {
      "field_statistics": {
        "sum_doc_freq": 4,
        "doc_count": 2,
        "sum_ttf": 6
      },
      "terms": {
        "test": {
          "doc_freq": 2,
          "ttf": 4,
          "term_freq": 3,
          "tokens": [
            {
              "position": 0,
              "start_offset": 0,
              "end_offset": 4,
              "payload": "d29yZA=="
            },
            {
              "position": 1,
              "start_offset": 5,
              "end_offset": 9,
              "payload": "d29yZA=="
            },
            {
              "position": 2,
              "start_offset": 10,
              "end_offset": 14,
              "payload": "d29yZA=="
            }
          ]
        }
      }
    }
  }
}

动态生成词向量编辑

未显式存储在索引中的词向量会动态自动计算。以下请求返回文档 1 中字段的所有信息和统计信息,即使词条尚未显式存储在索引中。请注意,对于字段 text,不会重新生成词条。

response = client.termvectors(
  index: 'my-index-000001',
  id: 1,
  body: {
    fields: [
      'text',
      'some_field_without_term_vectors'
    ],
    offsets: true,
    positions: true,
    term_statistics: true,
    field_statistics: true
  }
)
puts response
GET /my-index-000001/_termvectors/1
{
  "fields" : ["text", "some_field_without_term_vectors"],
  "offsets" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}

人工文档编辑

也可以为人工文档生成词向量,即为索引中不存在的文档生成词向量。例如,以下请求将返回与示例 1 中相同的结果。使用的映射由 index 确定。

如果启用了动态映射(默认),则将动态创建原始映射中没有的文档字段。

response = client.termvectors(
  index: 'my-index-000001',
  body: {
    doc: {
      fullname: 'John Doe',
      text: 'test test test'
    }
  }
)
puts response
GET /my-index-000001/_termvectors
{
  "doc" : {
    "fullname" : "John Doe",
    "text" : "test test test"
  }
}
每字段分析器编辑

此外,可以使用 `per_field_analyzer` 参数提供与字段中不同的分析器。这对于以任何方式生成词向量非常有用,尤其是在使用人工文档时。当为已存储词向量的字段提供分析器时,将重新生成词向量。

response = client.termvectors(
  index: 'my-index-000001',
  body: {
    doc: {
      fullname: 'John Doe',
      text: 'test test test'
    },
    fields: [
      'fullname'
    ],
    per_field_analyzer: {
      fullname: 'keyword'
    }
  }
)
puts response
GET /my-index-000001/_termvectors
{
  "doc" : {
    "fullname" : "John Doe",
    "text" : "test test test"
  },
  "fields": ["fullname"],
  "per_field_analyzer" : {
    "fullname": "keyword"
  }
}

响应

{
  "_index": "my-index-000001",
  "_version": 0,
  "found": true,
  "took": 6,
  "term_vectors": {
    "fullname": {
       "field_statistics": {
          "sum_doc_freq": 2,
          "doc_count": 4,
          "sum_ttf": 4
       },
       "terms": {
          "John Doe": {
             "term_freq": 1,
             "tokens": [
                {
                   "position": 0,
                   "start_offset": 0,
                   "end_offset": 8
                }
             ]
          }
       }
    }
  }
}

词条过滤编辑

最后,可以根据词条的 tf-idf 分数过滤返回的词条。在下面的示例中,我们从具有给定“plot”字段值的人工文档中获取了三个最“有趣”的关键字。请注意,关键字“Tony”或任何停用词都不是响应的一部分,因为它们的 tf-idf 值一定太低。

response = client.termvectors(
  index: 'imdb',
  body: {
    doc: {
      plot: 'When wealthy industrialist Tony Stark is forced to build an armored suit after a life-threatening incident, he ultimately decides to use its technology to fight against evil.'
    },
    term_statistics: true,
    field_statistics: true,
    positions: false,
    offsets: false,
    filter: {
      max_num_terms: 3,
      min_term_freq: 1,
      min_doc_freq: 1
    }
  }
)
puts response
GET /imdb/_termvectors
{
  "doc": {
    "plot": "When wealthy industrialist Tony Stark is forced to build an armored suit after a life-threatening incident, he ultimately decides to use its technology to fight against evil."
  },
  "term_statistics": true,
  "field_statistics": true,
  "positions": false,
  "offsets": false,
  "filter": {
    "max_num_terms": 3,
    "min_term_freq": 1,
    "min_doc_freq": 1
  }
}

响应

{
   "_index": "imdb",
   "_version": 0,
   "found": true,
   "term_vectors": {
      "plot": {
         "field_statistics": {
            "sum_doc_freq": 3384269,
            "doc_count": 176214,
            "sum_ttf": 3753460
         },
         "terms": {
            "armored": {
               "doc_freq": 27,
               "ttf": 27,
               "term_freq": 1,
               "score": 9.74725
            },
            "industrialist": {
               "doc_freq": 88,
               "ttf": 88,
               "term_freq": 1,
               "score": 8.590818
            },
            "stark": {
               "doc_freq": 44,
               "ttf": 47,
               "term_freq": 1,
               "score": 9.272792
            }
         }
      }
   }
}