ES学习记录9——关于Term

9.2.4 Term Vector

 返回一个特定文档的信息和字段的统计信息,这里的文档可以索引中存储的文档,也可以是用户手动提供的,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

  • 字段中term的频率(总是被返回);
  • term的定位(positions: true);
  • 开始和偏移(offsets: true);
  • term payloads(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 可能是有用的,下面是支持的子参数:

max_num_terms

每个字段必须返回的最大term数量,默认 25

min_term_freq

忽略源文档中低于此频率的单词,默认 1

max_term_freq

忽略源文档中超过此频率的单词,默认无界

min_doc_freq

忽略至少在这么多文档中没有出现的术语,默认 1.

max_doc_freq

忽略超过这么多文档中出现的单词,默认无界

min_word_length

最小字长,低于该字长将被忽略,默认 0.

max_word_length

最大字长,高于该字长将被忽略,默认无界 (0).

行为

 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一样的响应,使用的映射由indextype决定。如果动态映射是打开的状态(默认就是打开的),不在原始映射的文档字段将会被动态创建。

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
            }
         }
      }
   }
}

9.2.5 Multi termvectors 接口

 这个接口允许一次获取多个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 ..."
         }
      }
   ]
}

你可能感兴趣的:(#,ES,Elasticsearch)