Elasticsearch7.x——Term vector API详解

本文围绕Elasticsearch的Term向量展开,介绍其是在index document时产生,默认禁用,需在字段mapping中设置启用。阐述了term vector的配置选项、数据结构、返回值信息,包括Term信息、统计信息和字段统计信息,还提及Term过滤、行为分析及获取多个文档的Term向量等内容。

Term向量

词项向量(term vector)是有elasticsearch在index document的时候产生,其包含对document解析过程中产生的分词的一些信息,例如分词在字段值中的位置、开始和结束的字符位置、分词的元数据payloads等;

term vector是单独进行存储的,会额外多占用一杯的空间,所以elasticsearch默认情况下禁用词项向量,如果要启用,我们需要在字段的mapping中使用term_vector进行设置;

1、term_vector的配置选项

配置选项描述
no不启用term vector,默认值
yes启用term vector,但是仅记录分词
with_positions启用term vector, 记录分词及分词在字符串中的位置
with_offsets启用term vector, 记录分词在字符串中的起始字符位置
with_positions_offsets启用term vector, 记录分词在字符串中的位置及起始的字符位置
with_positions_payloads启用term vector, 记录分词在字符串中的位置及payloads
with_positions_offsets_payloads启用term vector, 记录分词在字符串中的位置、起始字符位置及payloads
PUT /twitter
{ "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"
          ]
        }
      }
    }
  }
}

将以下两个document发送到elasticsearch进行index:

PUT /twitter/_doc/1
{
  "fullname" : "John Doe",
  "text" : "twitter test test test "
}

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

2、查看term vector的数据结构

term vector主要由term information、term statistics、field statistics构成,其中term information又分成了positions、offsets、payloads三个选项,我们可以通过请求的body的参数分别控制返回的信息;

//语法:
GET /<index>/_termvectors/<_id>

示例:

GET /twitter/_termvectors/1
{
  "fields" : ["text"],
  "offsets" : true,
  "payloads" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}
//返回
{
  "_index" : "twitter",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "took" : 0,
  "term_vectors" : {
    "text" : {
      "field_statistics" : {
        "sum_doc_freq" : 6,
        "doc_count" : 2,
        "sum_ttf" : 8
      },
      "terms" : {
        "test" : {
          "doc_freq" : 2,
          "ttf" : 4,
          "term_freq" : 3,
          "tokens" : [
            {
              "position" : 1,
              "start_offset" : 8,
              "end_offset" : 12,
              "payload" : "d29yZA=="
            },
            {
              "position" : 2,
              "start_offset" : 13,
              "end_offset" : 17,
              "payload" : "d29yZA=="
            },
            {
              "position" : 3,
              "start_offset" : 18,
              "end_offset" : 22,
              "payload" : "d29yZA=="
            }
          ]
        },
        "twitter" : {
          "doc_freq" : 2,
          "ttf" : 2,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 7,
              "payload" : "d29yZA=="
            }
          ]
        }
      }
    }
  }
}

3、返回值信息

可以请求三种类型的值:Term信息、Term统计信息和字段统计 信息。默认情况下,返回所有字段的所有Term信息和字段统计信息, 但不返回Term统计信息。

基于以下两点term statistics和field statistics并不是准确的;

  • 删除的文档不会计算在内;
  • 只计算请求文档所在的分片的数据;

3.1、Term信息

  • term_freq:Term的频率(在对应字段中),这部分信息是始终返回的。
  • position:Term的位置,需要设置positions:true。
  • start_offset、end_offset:Term开始和结束的偏移量,需要设置offsets:true。
  • payload:分词的元数据,可以看到每个分词的payload都是d29yZA==,从这里可以到elasticsearch默认值为 word;

Term信息在Elasticsearch中的具体存储格式如图所示:
在这里插入图片描述

如果请求的信息没有存储在索引中,可能的话,它将被动态计算。此外,还可以为索引中不存在但由用户提供的文档计算Term向量。

开始和结束偏移量假定使用了UTF-16编码。如果要使用这些偏 移量来获取原始文本,应确保子字符串也使用UTF-16编码。

3.2、Term统计信息

需要将term_statistics设置为true,其默认值为false。Term统 计信息包括如下两方面的信息:

  • ttf(total term frequency):Term的总词频,即在所有文档中Term出现的总次数。可以看到twitter的ttf是2,test的ttf是4;
  • doc_freq(document frequency):当前字段包含当前分词的文档的数量,可以看到两个document的text字段都包含test及twitter,所以两者的doc_freq为2;

默认情况下,不会返回这些信息,因为Term统计信息可能会对性 能产生严重影响。

3.3、字段统计信息

字段统计信息默认是返回的,可以将field_statistics设为false来 禁止返回。字段统计信息包括如下三方面的内容:

  • doc_count:文档计数,即多少个文档存在这个字段值。这里两个文档都包含text字段,所以doc_count为2;

  • sum_doc_freq:文档频率总和,当前字段中所有分词对应的document frequency的加和。 这里以下计算可以得到sum_doc_freq为6;
    在这里插入图片描述

  • sum_ttf:Term频率总和,当前字段中所有分词对应的total term frequency的加和,这里以下计算可以得到sum_ttf为8;
    在这里插入图片描述

4、Term过滤

使用参数filter,还可以根据tf-idf分数过滤返回的Term。这有助 于找出文档的特征向量。此功能的工作方式更类似于此查询的第二阶 段。

在下面的示例中,从具有给定plot字段值的文档中获得三个用户 “最感兴趣”的关键字。请注意,关键字Tony或任何停止词都不是响 应的一部分,因为它们的tf-idf太低。

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",
   "_type": "_doc",
   "_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
            }
         }
      }
   }
}

可以在请求中传递以下子参数:

  • max_num_terms:每个字段返回的最大Term数。默认值 为25。也就是只有一个字段最多25个Term。
  • min_term_freq:忽略源文档中低于此频率的单词。默认值 为1。
  • max_term_freq:忽略源文档中超过此频率的单词。默认为 无限大。
  • min_doc_freq:忽略文档频率低于这个值的Term。默认值 为1。
  • max_doc_freq:忽略文档频率高于这个值的Term。默认值 为1。
  • min_word_length:忽略低于此值的Term。默认值为0。
  • max_word_length:忽略高于此值的Term。默认值为无穷 大。

5、行为分析

Term和Field统计信息是不准确的,仅检索请求文档所在的分片 的信息,而删除的文档不考虑在内。因此,Term和Field统计信息仅 用作相对测量,而绝对数值在此上下文中没有意义。默认情况下,当 请求人工文档的Term向量时,将随机选择一个分片来获取统计信息。 使用routing只命中特定的分片。

5.1、返回存储Term向量

以下请求返回ID为1的文档(john doe)中字段text的所有信息 和统计信息:

GET /twitter/_termvectors/1
{
  "fields" : ["text"],
  "offsets" : true,
  "payloads" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}
{
  "_index" : "twitter",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "took" : 0,
  "term_vectors" : {
    "text" : {
      "field_statistics" : {
        "sum_doc_freq" : 6,
        "doc_count" : 2,
        "sum_ttf" : 8
      },
      "terms" : {
        "test" : {
          "doc_freq" : 2,
          "ttf" : 4,
          "term_freq" : 3,
          "tokens" : [
            {
              "position" : 1,
              "start_offset" : 8,
              "end_offset" : 12,
              "payload" : "d29yZA=="
            },
            {
              "position" : 2,
              "start_offset" : 13,
              "end_offset" : 17,
              "payload" : "d29yZA=="
            },
            {
              "position" : 3,
              "start_offset" : 18,
              "end_offset" : 22,
              "payload" : "d29yZA=="
            }
          ]
        },
        "twitter" : {
          "doc_freq" : 2,
          "ttf" : 2,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 7,
              "payload" : "d29yZA=="
            }
          ]
        }
      }
    }
  }
}

5.2、动态生成Term向量

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

PUT /twitter/_doc/3
{
  "fullname" : "Jane Doe",
  "text" : "Another twitter test ...",
  "filed_without_term_vector": "hello world"
}

GET /twitter/_termvectors/3
{
  "fields" : ["text", "filed_without_term_vector"],
  "offsets" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}
{
  "_index" : "twitter",
  "_type" : "_doc",
  "_id" : "3",
  "_version" : 1,
  "found" : true,
  "took" : 0,
  "term_vectors" : {
    "text" : {
      "field_statistics" : {
        "sum_doc_freq" : 10,
        "doc_count" : 3,
        "sum_ttf" : 12
      },
      "terms" : {
        "..." : {
          "doc_freq" : 2,
          "ttf" : 2,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 3,
              "start_offset" : 21,
              "end_offset" : 24,
              "payload" : "d29yZA=="
            }
          ]
        },
        "another" : {
          "doc_freq" : 2,
          "ttf" : 2,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 7,
              "payload" : "d29yZA=="
            }
          ]
        },
        "test" : {
          "doc_freq" : 3,
          "ttf" : 5,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 2,
              "start_offset" : 16,
              "end_offset" : 20,
              "payload" : "d29yZA=="
            }
          ]
        },
        "twitter" : {
          "doc_freq" : 3,
          "ttf" : 3,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 1,
              "start_offset" : 8,
              "end_offset" : 15,
              "payload" : "d29yZA=="
            }
          ]
        }
      }
    },
    "filed_without_term_vector" : {
      "field_statistics" : {
        "sum_doc_freq" : 2,
        "doc_count" : 1,
        "sum_ttf" : 2
      },
      "terms" : {
        "hello" : {
          "doc_freq" : 1,
          "ttf" : 1,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 5
            }
          ]
        },
        "world" : {
          "doc_freq" : 1,
          "ttf" : 1,
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 1,
              "start_offset" : 6,
              "end_offset" : 11
            }
          ]
        }
      }
    }
  }
}

5.3、人工文档

可以为人工文档生成Term向量,即索引中不存在的文档。示例如 下:

GET /twitter/_termvectors
{
  "doc" : {
    "fullname" : "John Doe",
    "text" : "twitter test test test"
  }
}
{
  "_index" : "twitter",
  "_type" : "_doc",
  "_version" : 0,
  "found" : true,
  "took" : 0,
  "term_vectors" : {
    "text" : {
      "field_statistics" : {
        "sum_doc_freq" : 10,
        "doc_count" : 3,
        "sum_ttf" : 12
      },
      "terms" : {
        "test" : {
          "term_freq" : 3,
          "tokens" : [
            {
              "position" : 1,
              "start_offset" : 8,
              "end_offset" : 12
            },
            {
              "position" : 2,
              "start_offset" : 13,
              "end_offset" : 17
            },
            {
              "position" : 3,
              "start_offset" : 18,
              "end_offset" : 22
            }
          ]
        },
        "twitter" : {
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 7
            }
          ]
        }
      }
    },
    "fullname" : {
      "field_statistics" : {
        "sum_doc_freq" : 6,
        "doc_count" : 3,
        "sum_ttf" : 6
      },
      "terms" : {
        "doe" : {
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 1,
              "start_offset" : 5,
              "end_offset" : 8
            }
          ]
        },
        "john" : {
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 4
            }
          ]
        }
      }
    }
  }
}

5.4、字段分析器

此外,可以使用per_field_analyzer参数为不同的字段提供不同 的分析器,这对于以任何方式生成Term向量都很有用,特别是在使用 人工文档时。当为已经存储Term向量的字段提供分析器时,将重新生 成Term向量。

GET /twitter/_termvectors
{
  "doc" : {
    "fullname" : "John Doe",
    "text" : "twitter test test test"
  },
  "fields": ["fullname"],
  "per_field_analyzer" : {
    "fullname": "keyword"
  }
}
{
  "_index" : "twitter",
  "_type" : "_doc",
  "_version" : 0,
  "found" : true,
  "took" : 0,
  "term_vectors" : {
    "fullname" : {
      "field_statistics" : {
        "sum_doc_freq" : 6,
        "doc_count" : 3,
        "sum_ttf" : 6
      },
      "terms" : {
        "John Doe" : {
          "term_freq" : 1,
          "tokens" : [
            {
              "position" : 0,
              "start_offset" : 0,
              "end_offset" : 8
            }
          ]
        }
      }
    }
  }
}

6、获取多个文档的Term向量

_mtermvectors API允许一次获取多个文档的Term向量。由索 引_index和_id参数指定多个文档,从指定的文档中检索出Term向 量。但是文档也可以在请求本身中人工提供。

//语法
POST /_mtermvectors
POST /<index>/_mtermvectors
POST /_mtermvectors
{
   "docs": [
      {
        "_index":"twitter",
         "_id": "2",
         "fields": [
            "message"
         ],
         "term_statistics": true
      },
      {
        "_index":"twitter",
         "_id": "1"
      }
   ]
}

响应包括一个docs数组,此数组包含所有获取的Term向量。

{
  "docs" : [
    {
      "_index" : "twitter",
      "_type" : "_doc",
      "_id" : "2",
      "_version" : 1,
      "found" : true,
      "took" : 0,
      "term_vectors" : { }
    },
    {
      "_index" : "twitter",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 1,
      "found" : true,
      "took" : 0,
      "term_vectors" : {
        "fullname" : {
          "field_statistics" : {
            "sum_doc_freq" : 6,
            "doc_count" : 3,
            "sum_ttf" : 6
          },
          "terms" : {
            "doe" : {
              "term_freq" : 1,
              "tokens" : [
                {
                  "position" : 1,
                  "start_offset" : 5,
                  "end_offset" : 8,
                  "payload" : "d29yZA=="
                }
              ]
            },
            "john" : {
              "term_freq" : 1,
              "tokens" : [
                {
                  "position" : 0,
                  "start_offset" : 0,
                  "end_offset" : 4,
                  "payload" : "d29yZA=="
                }
              ]
            }
          }
        },
        "text" : {
          "field_statistics" : {
            "sum_doc_freq" : 10,
            "doc_count" : 3,
            "sum_ttf" : 12
          },
          "terms" : {
            "test" : {
              "term_freq" : 3,
              "tokens" : [
                {
                  "position" : 1,
                  "start_offset" : 8,
                  "end_offset" : 12,
                  "payload" : "d29yZA=="
                },
                {
                  "position" : 2,
                  "start_offset" : 13,
                  "end_offset" : 17,
                  "payload" : "d29yZA=="
                },
                {
                  "position" : 3,
                  "start_offset" : 18,
                  "end_offset" : 22,
                  "payload" : "d29yZA=="
                }
              ]
            },
            "twitter" : {
              "term_freq" : 1,
              "tokens" : [
                {
                  "position" : 0,
                  "start_offset" : 0,
                  "end_offset" : 7,
                  "payload" : "d29yZA=="
                }
              ]
            }
          }
        }
      }
    }
  ]
}

可以指定索引:

POST /twitter/_mtermvectors
{
   "docs": [
      {
         "_id": "2",
         "fields": [
            "message"
         ],
         "term_statistics": true
      },
      {
         "_id": "1"
      }
   ]
}

如果所有请求的文档都在同一索引上,并且参数相同,则可以简 化请求:

POST /twitter/_mtermvectors
{
    "ids" : ["1", "2"],
    "parameters": {
    	"fields": [
         	"message"
      	],
      	"term_statistics": true
    }
}

此外,可以为用户提供的文档生成Term向量。使用的映射由索引 _index确定。下面是具体的实例:

POST /_mtermvectors
{
   "docs": [
      {
         "_index": "twitter",
         "doc" : {
            "user" : "John Doe",
            "message" : "twitter test test test"
         }
      },
      {
         "_index": "twitter",
         "doc" : {
           "user" : "Jane Doe",
           "message" : "Another twitter test ..."
         }
      }
   ]
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值