这篇文章有点深度,可能需要一些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
}
}
}
}
}

在Elasticsearch中查询Term Vectors词条向量信息的更多相关文章

  1. Elasticsearch中的Term查询和全文查询

    目录 前言 Term 查询 exists 查询 fuzzy 查询 ids 查询 prefix 查询 range 查询 regexp 查询 term 查询 terms 查询 terms_set 查询 t ...

  2. SQL Server中查询数据库及表的信息语句

    /* -- 本文件主要是汇总了 Microsoft SQL Server 中有关数据库与表的相关信息查询语句. -- 下面的查询语句中一般给出两种查询方法, -- A方法访问系统表,适应于SQL 20 ...

  3. elasticsearch中的mapping映射配置与查询典型案例

    elasticsearch中的mapping映射配置与查询典型案例 elasticsearch中的mapping映射配置示例比如要搭建个中文新闻信息的搜索引擎,新闻有"标题".&q ...

  4. ElasticSearch中的简单查询

    前言 最近修改项目,又看了下ElasticSearch中的搜索,所以简单整理一下其中的查询语句等.都是比较基础的.PS,好久没写博客了..大概就是因为懒吧.闲言少叙书归正传. 查询示例 http:// ...

  5. ES 22 - Elasticsearch中如何进行日期(数值)范围查询

    目录 1 范围查询的符号 2 数值范围查询 3 时间范围查询 3.1 简单查询示例 3.2 关于时间的数学表达式(date-math) 3.3 关于时间的四舍五入 4 日期格式化范围查询(format ...

  6. ElasticSearch常用查询命令-kibana中使用

    目录 初学ES 只创建索引(表) 1. 创建 2.创建好后查看索引结构 添加文档(数据) 查看文档(数据) 修改文档数据(数据update) put方式修改 post方式修改 删除文档&索引 ...

  7. elasticsearch中常用的API

    elasticsearch中常用的API分类如下: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作,查看索引信息等 查看API: ...

  8. elasticsearch中的API

    elasticsearch中的API es中的API按照大类分为下面几种: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作 查看A ...

  9. Elasticsearch中的相似度模型(原文:Similarity in Elasticsearch)

    原文链接:https://www.elastic.co/blog/found-similarity-in-elasticsearch 原文 By Konrad Beiske 翻译 By 高家宝 译者按 ...

随机推荐

  1. 用python实现,冒泡排序演示

    # -*- coding:utf-8 -*- import time from Tkinter import * a=[1,9,5,6,8,1] class CanvasDemo(): #n1=70 ...

  2. Linux之源码包安装软件

    安装准备      安装c语言编辑器 gcc      压缩包  node-v6.2.0-linux-x64.tar.gz   源码包保存位置  /usr/local/src/ 源码包安装位置 /us ...

  3. 【腾讯优测干货】看腾讯的技术大牛如何将Crash率从2.2%降至0.2%?

    小优有话说: App Crash就像地雷. 你怕它,想当它不存在.无异于让你的用户去探雷,一旦引爆,用户就没了. 你鼓起勇气去扫雷,它却神龙见首不见尾. 你告诫自己一定开发过程中减少crash,少埋点 ...

  4. 如何捕获和分析 JavaScript Error

    前端工程师都知道 JavaScript 有基本的异常处理能力.我们可以 throw new Error(),浏览器也会在我们调用 API 出错时抛出异常.但估计绝大多数前端工程师都没考虑过收集这些异常 ...

  5. HyperDock,让Mac的窗口飞

    三年前写了一篇文章,介绍了Windows 7下的Aero效果,其实最终是想引出来写Mac OS上能产生类似功能的HyperDock应用程序,可惜这一拖,就拖到连Windows 10都快要发布了.没有关 ...

  6. 生成格式化的json

    public static ContentResult returnJson(object obj) { var content = new ContentResult() { Content = J ...

  7. 每天一个linux命令(11):nl命令

    nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等 ...

  8. android TextView 文字垂直的设置

    <TextView android:id="@+id/tv_status" android:layout_width="wrap_content" and ...

  9. java中string内存的相关知识点

    (一):区别java内存中堆和栈: 1.栈:数据可以共享,存放基本数据类型和对象的引用,其中对象存放在堆中,对象的引用存放在栈中: 当在一段代码块定义一个变量时,就在栈中 为这个变量分配内存空间,当该 ...

  10. ListView优化为何ViewHolder用static类(转载)

    如果有人还不了解ViewHolder为什么可以起到优化作用,我这边再做下简单说明:Android的findViewById动作是比较耗时的,需要遍历布局的树形结构,才能找到相应的视图.所以如果想在这一 ...