在Elasticsearch中查询Term Vectors词条向量信息

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介:

这篇文章有点深度,可能需要一些Lucene或者全文检索的背景。由于我也很久没有看过Lucene了,有些地方理解的不对还请多多指正。
更多内容还请参考整理的ELK教程

关于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字段对返回的统计信息的字段进行过滤,只返回感兴趣的那部分内容。

例子1:返回存储的Term Vectors信息

首先需要定义一下映射的信息:

curl -s -XPUT 'http://localhost:9200/twitter/' -d '{
  "mappings": {
    "tweet": {
      "properties": {
        "text": {
          "type": "string",
          "term_vector": "with_positions_offsets_payloads",
          "store" : true,
          "analyzer" : "fulltext_analyzer"
         },
         "fullname": {
          "type": "string",
          "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"
          ]
        }
      }
    }
  }
}'

然后插入两条数据:

curl -XPUT 'http://localhost:9200/twitter/tweet/1?pretty=true' -d '{
  "fullname" : "John Doe",
  "text" : "twitter test test test "
}'

curl -XPUT 'http://localhost:9200/twitter/tweet/2?pretty=true' -d '{
  "fullname" : "Jane Doe",
  "text" : "Another twitter test ..."
}'

接下来查询一下文档1的Term Vectors信息:

curl -XGET 'http://localhost:9200/twitter/tweet/1/_termvectors?pretty=true' -d '{
  "fields" : ["text"],
  "offsets" : true,
  "payloads" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}'

可以得到下面的结果:

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

可以看到上面返回了词条的统计信息,以及字段的统计信息。

例子2:轻量级生成Term Vectors

虽然这个字段不是显示存储的,但是仍然可以进行词条向量的信息统计。因为ES可以在查询的时候,从_source中分析出相应的内容。

curl -XGET 'http://localhost:9200/twitter/tweet/1/_termvectors?pretty=true' -d '{
  "fields" : ["text", "some_field_without_term_vectors"],
  "offsets" : true,
  "positions" : true,
  "term_statistics" : true,
  "field_statistics" : true
}'

关于字段的存储于不存储,可以简单的理解为:

  • 如果字段存储,在ES进行相关的查询时,会直接从存储的字段读取信息
  • 如果字段不存储,ES会从_source中查询分析,提取相应的部分。

由于每次读取操作都是一次的IO,因此如果你不是只针对某个字段、或者_source中的信息太多,那么请优先不存储该字段,即从_source中获取就好。

例子3:手动自定义的文档统计

ES支持对一个用户自定义的文档进行分析,比如:

curl -XGET 'http://localhost:9200/twitter/tweet/_termvectors' -d '{
  "doc" : {
    "fullname" : "John Doe",
    "text" : "twitter test test test"
  }
}'

注意如果这个字段没有预先定义映射,那么会按照默认的映射配置进行分析。

例子4:重新定义分析器

可以使用per_field_analyzer参数定义该字段的分析器,这样每个字段都可以使用不同的分析器,分析其词条向量的信息。如果这个字段已经经过存储,那么会重新生成它的词条向量,如:

curl -XGET 'http://localhost:9200/twitter/tweet/_termvectors' -d '{
  "doc" : {
    "fullname" : "John Doe",
    "text" : "twitter test test test"
  },
  "fields": ["fullname"],
  "per_field_analyzer" : {
    "fullname": "keyword"
  }
}'

会返回:

{
  "_index": "twitter",
  "_type": "tweet",
  "_version": 0,
  "found": true,
  "term_vectors": {
    "fullname": {
       "field_statistics": {
          "sum_doc_freq": 1,
          "doc_count": 1,
          "sum_ttf": 1
       },
       "terms": {
          "John Doe": {
             "term_freq": 1,
             "tokens": [
                {
                   "position": 0,
                   "start_offset": 0,
                   "end_offset": 8
                }
             ]
          }
       }
    }
  }
}

例子5:字段过滤器

在进行词条向量的信息查询时,可以根据自定义的过滤器,返回感兴趣的信息。

常用的过滤器参数如:

  • max_num_terms 最大的词条数目
  • min_term_freq 最小的词频,比如忽略那些在字段中出现次数小于一定值的词条。
  • max_term_freq 最大的词频
  • min_doc_freq 最小的文档频率,比如忽略那些在文档中出现次数小于一定的值的词条
  • max_doc_freq 最大的文档频率
  • min_word_length 忽略的词的最小长度
  • max_word_length 忽略的词的最大长度
GET /imdb/movies/_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,
    "dfs": true,
    "positions": false,
    "offsets": false,
    "filter" : {
      "max_num_terms" : 3,
      "min_term_freq" : 1,
      "min_doc_freq" : 1
    }
}

会返回:

{
   "_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
            }
         }
      }
   }
}
本文转自博客园xingoo的博客,原文链接:在Elasticsearch中查询Term Vectors词条向量信息,如需转载请自行联系原博主。
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
4天前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
21 0
|
4天前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
16 0
|
1月前
|
JSON 自然语言处理 算法
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
DSL查询文档、RestClient查询文档、全文检索查询、精准查询、复合查询、地理坐标查询、分页、排序、高亮、黑马旅游案例
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
|
2月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
36 1
|
2月前
|
存储 自然语言处理 Java
ElasticSearch 实现分词全文检索 - 经纬度定位商家距离查询
ElasticSearch 实现分词全文检索 - 经纬度定位商家距离查询
17 0
|
1月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
2月前
|
数据可视化 Docker 容器
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
这篇文章提供了通过Docker安装Elasticsearch和Kibana的详细过程和图解,包括下载镜像、创建和启动容器、处理可能遇到的启动失败情况(如权限不足和配置文件错误)、测试Elasticsearch和Kibana的连接,以及解决空间不足的问题。文章还特别指出了配置文件中空格的重要性以及环境变量中字母大小写的问题。
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
|
2月前
|
JSON 自然语言处理 数据库
Elasticsearch从入门到项目部署 安装 分词器 索引库操作
这篇文章详细介绍了Elasticsearch的基本概念、倒排索引原理、安装部署、IK分词器的使用,以及如何在Elasticsearch中进行索引库的CRUD操作,旨在帮助读者从入门到项目部署全面掌握Elasticsearch的使用。
|
2月前
|
Ubuntu Oracle Java
如何在 Ubuntu VPS 上安装 Elasticsearch
如何在 Ubuntu VPS 上安装 Elasticsearch
23 0
|
2月前
|
存储 Ubuntu Oracle
在Ubuntu 14.04上安装和配置Elasticsearch的方法
在Ubuntu 14.04上安装和配置Elasticsearch的方法
32 0

热门文章

最新文章