返回一个特定文档的信息和字段的统计信息,这里的文档可以索引中存储的文档,也可以是用户手动提供的,Term vector默认是实时的(而不是接近实时),这可以通过realtime=false
进行更改,下面是个小栗子:
GET /twitter/_doc/1/_termvectors
// 也可以使用url中的参数指定为检索信息的字段
GET /twitter/_doc/1/_termvectors?fields=message
或者也可以在请体中添加请求字段,还可以使用通配符匹配指定的字段,注意/_termvector
在ES 2.0中就已经被弃用了,替换为/_termvectors
。
返回值
有三类值可以被请求:term information, term statistics and field statistics,默认情况下,所有的term information和字段statistics都会被返回,但term statistics不返回。
term information
positions
: true);offsets
: true);payloads
: true)作为base64编码字节。如果请求信息没有存储在索引中,如果可能的话它将在运行时计算。此外,trem vetors可以不仅仅计算索引中已存在的文档,而且可以包含用户提供的文档。
Term statistics(Term统计信息,即将该某个字段里面的单词全都拆开成独立的单词进行分析)
将term_statistics
设置为true
将会返回这个Term statistics:
term_freq
(total term frequency),term的频率(在当前文档中该term出现的次数);doc_freq
(document frequency)文档频率(包含当前term的文档数量,含有该term的文档有多少);ttf
(该term在所有文档中出现的次数)tokens
包含该term的详细信息:
position
:以单词为单位(不含空格),一个单词占一个索引,从0开始,表示该term的索引位置;start_offset
:以字符为单位(包含空格),一个字符占一个索引,从0开始,表示该term的第一个字符的索引位置(包含该位置);end_offset
:以字符为单位(包含空格),一个字符占一个索引,从0开始,表示该term的最后一个字符的索引位置(不包含该位置);payload
:主要用于自定字段的权重;默认情况下,这些值不会被返回,因为term statistics可能会对性能有严重的影响。
Field statistics(字段统计信息)
将field_statistics
(默认为true
)设置为false
将会忽略:
doc_sount
文档数(索引下总共有多少文档包含了这个字段,只要字段名相同就算,字段值不一定要相同);sum_doc_freq
文档频率的总和(在这个字段中所有term的文档频率总和,这里理解下来,每个文档中该字段中总共含有多个单词,将所有包含该字段的文档都这样计算后进行加和即可,注意同一个文档中重复出现的单词只算一次,不同文档中含有相同单词可以重复算);sum_ttf
(sum of total term frequencies)总的term频率之和(在该字段中每个trem的总频率之和,我自己理解下来就是每个文档中该字段中总共含有多个单词,将所有包含该字段的文档都这样计算后进行加和,这里不管同一文档中对应字段中的单词是否重复);Terms Filtering
使用filter
参数,还可以根据其 tf-idf 的分数过滤返回的term,这对于找出文档的良好特征 term 可能是有用的,下面是支持的子参数:
|
每个字段必须返回的最大term数量,默认 |
|
忽略源文档中低于此频率的单词,默认 |
|
忽略源文档中超过此频率的单词,默认无界 |
|
忽略至少在这么多文档中没有出现的术语,默认 |
|
忽略超过这么多文档中出现的单词,默认无界 |
|
最小字长,低于该字长将被忽略,默认 |
|
最大字长,高于该字长将被忽略,默认无界 ( |
行为
term和字段统计并不是准确的,删除的文档也是计算到里面的,仅为请求的文档所在的分片检索信息。因此,term和字段统计仅用作相对度量,而绝对数量在此上下文中没有意义。默认情况下,当人造文档请求term vector,从随机选择的碎片中获取统计信息,使用routing
取寻找命中特定的碎片。
案例1:返回存储的term vetors
// 1.创建一个存储了term vectors的索引
PUT /twitter/
{ "mappings": {
"_doc": { // 文档类型
"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"
]
}
}
}
}
}
// 2.往索引中添加文档
PUT /twitter/_doc/1
{
"fullname" : "John Doe",
"text" : "twitter test test test "
}
PUT /twitter/_doc/2
{
"fullname" : "Jane Doe",
"text" : "Another twitter test ..."
}
// 3.获取id为1的文档所有信息和text字段的统计信息
GET /twitter/_doc/1/_termvectors
{
"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": 11,
"term_vectors": {
"text": {
"field_statistics": {
"sum_doc_freq": 6, // 文档1中text字段含2个单词(test出现3次只能算一次),文档2中含4个单词,所以总共是6
"doc_count": 2, // 文档1和2都包含text字段,所以为2
"sum_ttf": 8 // 文档1中text字段含4个单词,同样文档2含4个单词,总和为8
},
"terms": {
"test": {
"doc_freq": 2, // “test”这个term总共在文档1和文档2中出现过,所以出现term的文档上为2
"ttf": 4,
"term_freq": 3, // 在文档1中“test”这个term出现了3次
"tokens": [
{
"position": 1, // 第一个test在1号位出现
"start_offset": 8, // test的第一个字符从8号位开始
"end_offset": 12, // test的在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=="
}
]
}
}
}
}
}
案例2:运行时生成term vectors
未明确存储在索引中的term vectors将在运行中自动计算,以下请求将返回id为1的文档中字段的所有信息和统计信息,即使这些term尚未明确存储在索引中,注意对于text
字段,term不会重新生成。
GET /twitter/_doc/1/_termvectors
{
"fields" : ["text", "some_field_without_term_vectors"],
"offsets" : true,
"positions" : true,
"term_statistics" : true,
"field_statistics" : true
}
案例3: 手动给的文档
Term vector也可以使用人造文档生成,适用于不在索引中的文档,比如这个案例将会返回和案例1一样的响应,使用的映射由index
和type
决定。如果动态映射是打开的状态(默认就是打开的),不在原始映射的文档字段将会被动态创建。
GET /twitter/_doc/_termvectors
{
"doc" : {
"fullname" : "John Doe",
"text" : "twitter test test test"
}
}
此外,可以通过使用per_field_analyzer
参数提供与现场不同的分析器。这对于以任何方式生成term vector是有用的,尤其是在使用人工文档时。当为已经存储term vector的字段提供分析器时,term vector将重新生成:
GET /twitter/_doc/_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": 4,
"doc_count": 2,
"sum_ttf": 4
},
"terms": {
"John Doe": {
"term_freq": 1,
"tokens": [
{
"position": 0,
"start_offset": 0,
"end_offset": 8
}
]
}
}
}
}
}
案例4: term 过滤
返回的 term 可以基于它们的 tf-idf 分数进行过滤,下面的这个案例从具备被给的plot
字段值的人造文档获取3个最有意思的关键词,注意关键词Tony
或者任何停止的单词都不是响应的一部分,作为它们的 tf-idf 必须很低,小栗子如下:
GET /imdb/_doc/_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
}
}
// 上述的例子我没有调试通过404,索引改成本地索引后term vector中为空
{
"_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
}
}
}
}
}
这个接口允许一次获取多个termvector,检索 term vector 的文档由index、type、id指定,但是这些文档也可以是在请求体中人工提供的。响应包含了一个包含所有获取的 termvectors 的doc
数组,每个元素有由termvectors接口提供的结构体。
POST /_mtermvectors
{
"docs": [
{
"_index": "twitter",
"_type": "_doc",
"_id": "2",
"term_statistics": true
},
{
"_index": "twitter",
"_type": "_doc",
"_id": "1",
"fields": [
"message"
]
}
]
}
_mtermvectors
端点也可以用于索引,这种情况下请求不是必需的:
POST /twitter/_mtermvectors
{
"docs": [
{
"_type": "_doc",
"_id": "2",
"fields": [
"message"
],
"term_statistics": true
},
{
"_type": "_doc",
"_id": "1"
}
]
}
// 以及这一类
POST /twitter/_doc/_mtermvectors
{
"docs": [
{
"_id": "2",
"fields": [
"message"
],
"term_statistics": true
},
{
"_id": "1"
}
]
}
如果所有的请求的文档都在同一个索引下的同一个类型中,并且参数也一样,那请求可以简写成:
POST /twitter/_doc/_mtermvectors
{
"ids" : ["1", "2"],
"parameters": {
"fields": [
"message"
],
"term_statistics": true
}
}
此外,和termvectors接口一样, term vector 将会为提供文档的用户生成,使用的映射由_index
和_type
决定:
POST /_mtermvectors
{
"docs": [
{
"_index": "twitter",
"_type": "_doc",
"doc" : {
"user" : "John Doe",
"message" : "twitter test test test"
}
},
{
"_index": "twitter",
"_type": "_doc",
"doc" : {
"user" : "Jane Doe",
"message" : "Another twitter test ..."
}
}
]
}