Elasticsearch在Elasticsearch中查询Term Vectors词条向量信息
Posted 九师兄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch在Elasticsearch中查询Term Vectors词条向量信息相关的知识,希望对你有一定的参考价值。
1.概述
转载:https://www.cnblogs.com/xing901022/p/5348737.html
关于Term Vectors
额,对于这个专业词汇,暂且就叫做词条向量吧,因为实在想不出什么标准的翻译。说的土一点,也可以理解为关于词的一些统计信息。再说的通俗点,如果想进行全文检索,即从一个词搜索与它相关的文档,总得有个什么记录的信息吧!这就是Term Vectors。
为了不干扰正常的理解,后续就都直接称呼英文的名字吧!免得误导…
先不看这篇文章,如果想要记录全文检索的信息,大家设想一下我们都需要什么内容,就拿"hello world! hello everybody!"来举例。
- 首先就是这句话都有什么词,“hello”,“world”,“everybody”
- 然后是这些词关联的文档,因为有可能不止上面这一句话。
- 最后就是词在文档中的位置,比如hello,出现了两次,就需要记录两份位置信息。
关于TermVector在Lucene中的概念,可以参考网络中的一篇文章
使用_termvectors查询词条向量
在Elasticsearch中可以使用_termvectors查询一个文档中词条相关的信息。这个文档可能是es中存储的,也可能是用户直接在请求体中自定义的。这个方法默认是一个实时的统计信息。
常见的语法如:
curl -XGET 'http://localhost:9200/twitter/tweet/1/_termvectors?pretty=true'
也可以指定某个字段,返回这个字段的信息:
curl -XGET 'http://localhost:9200/twitter/tweet/1/_termvectors?fields=text,...'
注意,在Elasticsearch中2.0之前都是使用_termvector,之后都是使用的_termvectors。
返回的信息
使用上面的请求,会返回词条相关的信息:
- 词条的信息,比如
position
位置、start_offset
开始的偏移值、end_offset
结束的偏移值、词条的payLoads(这个主要用于自定义字段的权重) - 词条统计,
doc_freq
、ttf该词出现的次数、term_freq词的频率 - 字段统计,包含sum_doc_freq该字段中词的数量(去掉重复的数目)、sum_ttf文档中词的数量(包含重复的数目)、doc_count涉及的文档数等等。
默认会返回词条的信息和统计,而不会返回字段的统计。
另外,默认这些统计信息是基于分片的,可以设置dfs为true,返回全部分片的信息,但是会有一定的性能问题,所以不推荐使用。还可以使用field字段对返回的统计信息的字段进行过滤,只返回感兴趣的那部分内容。
5.案例
5.1 例子1:返回存储的Term Vectors信息
首先需要定义一下映射的信息:
PUT /twitter-001/
{
"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"
]
}
}
}
}
}
然后插入两条数据:
PUT /twitter-001/_doc/1?pretty=true
{
"fullname" : "John Doe",
"text" : "twitter test test test "
}
PUT /twitter-001/_doc/2?pretty=true
{
"fullname" : "Jane Doe",
"text" : "Another twitter test ..."
}
接下来查询一下文档1的Term Vectors信息:
GET /twitter-001/_doc/1/_termvectors?pretty=true
{
"fields" : ["text"],
"offsets" : true,
"payloads" : true,
"positions" : true,
"term_statistics" : true,
"field_statistics" : true
}
可以得到下面的结果:
{
"_index" : "twitter-001",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"found" : true,
"took" : 69,
"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 例子2:轻量级生成Term Vectors
虽然这个字段不是显示存储的,但是仍然可以进行词条向量的信息统计。因为ES可以在查询的时候,从_source中分析出相应的内容。
GET /twitter-001/_doc/1/_termvectors?pretty=true
{
"fields" : ["text", "some_field_without_term_vectors"],
"offsets" : true,
"positions" : true,
"term_statistics" : true,
"field_statistics" : true
}
关于字段的存储于不存储,可以简单的理解为:
- 如果字段存储,在ES进行相关的查询时,会直接从存储的字段读取信息
- 如果字段不存储,ES会从_source中查询分析,提取相应的部分。
由于每次读取操作都是一次的IO
,因此如果你不是只针对某个字段、或者_source中的信息太多,那么请优先不存储该字段
,即从_source中获取就好。
5.3 例子3:手动自定义的文档统计
ES支持对一个用户自定义的文档进行分析,比如:
GET /twitter-001/_doc/_termvectors
{
"doc" : {
"fullname" : "John Doe",
"text" : "twitter test test test"
}
}
注意如果这个字段没有预先定义映射,那么会按照默认的映射配置进行分析。 结果如下
{
"_index" : "twitter-001",
"_type" : "_doc",
"_version" : 0,
"found" : true,
"took" : 21,
"term_vectors" : {
"fullname" : {
"field_statistics" : {
"sum_doc_freq" : 4,
"doc_count" : 2,
"sum_ttf" : 4
},
"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
}
]
}
}
},
"text" : {
"field_statistics" : {
"sum_doc_freq" : 6,
"doc_count" : 2,
"sum_ttf" : 8
},
"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
}
]
}
}
}
}
}
5.4 例子4:重新定义分析器
可以使用per_field_analyzer参数定义该字段的分析器,这样每个字段都可以使用不同的分析器,分析其词条向量的信息。如果这个字段已经经过存储,那么会重新生成它的词条向量,如:
GET /twitter-001/_doc/_termvectors
{
"doc" : {
"fullname" : "John Doe",
"text" : "twitter test test test"
},
"fields": ["fullname"],
"per_field_analyzer" : {
"fullname": "keyword"
}
}
结果如下
{
"_index" : "twitter-001",
"_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
}
]
}
}
}
}
}
5.5 例子5:字段过滤器
在进行词条向量的信息查询时,可以根据自定义的过滤器,返回感兴趣的信息。
常用的过滤器参数如:
max_num_terms 最大的词条数目
min_term_freq 最小的词频,比如忽略那些在字段中出现次数小于一定值的词条。
max_term_freq 最大的词频
min_doc_freq 最小的文档频率,比如忽略那些在文档中出现次数小于一定的值的词条
max_doc_freq 最大的文档频率
min_word_length 忽略的词的最小长度
max_word_length 忽略的词的最大长度
会返回:
{
"_index": "imdb",
"_type": "movies",
"_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
}
}
}
}
}
以上是关于Elasticsearch在Elasticsearch中查询Term Vectors词条向量信息的主要内容,如果未能解决你的问题,请参考以下文章