doc es 中type_es 搜索数据 分词

本文介绍了Elasticsearch中的中文分词,包括安装IK插件,如何获取词频,以及如何利用term vectors进行词频统计。重点讨论了text类型字段在聚合和排序中的限制,强调了fielddata对内存的影响及其开启方法。
摘要由CSDN通过智能技术生成

总结

1、能中文分词,安装ik插件,阿里云es默认就带有

2、获取词频

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-termvectors.html#docs-termvectors

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-termvectors.html

  1. 安装分词插件

1.需要中文分析。中文分词器有多种,ik为默认且较好,aliws(AliNLP分词)分的太细

2.需要分词更准确。导入关键词,扩展词典(词库),导入后需要重新索引文档

#测试分词效果
GET _analyze
{
"analyzer": "ik_smart",
"text": ["医生胃炎阴虚体寒的人能吃吗"]
}

       8c48531c3091841bd264c7e53cc57231.png      

https://help.aliyun.com/document_detail/137928.html?spm=a2c4g.11186623.6.638.1a8dfc44Q6OP3J

词典(词库)扩展

实践了es管理的的热更新,需要手动上传dic文件,首次文件会被要求重启服务,启动大约几分钟,所以需要晚上停止服务处理。

IK自带的主词库

SYSTEM_MAIN.dic

停用词主词库

SYSTEM_STOPWORD.dic

停用词是指在信息检索中,为节省存储空间和提高搜索效率,在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或,这些字或即被称为Stop Words(停用词)。这些停用词都是人工输入、非自动化生成的,生成后的停用词会形成一个停用词表。但是,并没有一个明确的停用词表能够适用于所有的工具。

  1. 存储(索引)能查词频的文档

1.定义文档的mapping(text,分词器)

PUT /ga_comment
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"reply_comment_id": {
"type": "keyword"
},
"platform_code": {
"type": "keyword"
},
"account_id": {
"type": "keyword"
},
"es_id": {
"type": "keyword"
},
"open_id": {
"type": "keyword"
},
"open_video_id": {
"type": "keyword"
},
"open_comment_id": {
"type": "keyword"
},
"account_name": {
"type": "text",
"analyzer" : "ik_smart"
},
"video_title": {
"type": "text",
"analyzer" : "ik_smart"
},
"content": {
"type": "text",
"term_vector": "yes",
"store" : true,
"analyzer" : "ik_smart"
},
"comment_time": {
"type": "date"
},
"pull_time": {
"type": "date"
},
"delete_time": {
"type": "date"
},
"create_time": {
"type": "date"
}
}
}
}

Term vectors是通过分析器解析产生的信息,包括:

  • 一组terms(词根)。

  • 每个词根的位置(顺序)。

  • 映射词根的首字符和尾字符与原始字符串原点的偏移量。

这些term vectors将被存储,一遍将他从一个特定的文档中取出。

term_vector 有一下参数设置:

no

不存储term vectors信息。(默认值)

yes

仅次字段中的terms(词根)被存储。

with_positions

存储词根和位置。

with_offset

存储词根和字符偏移量。

with_positions_offsets

存储词根、位置和字符偏移量。

fast vector highlighter需要用到 with_positions_offsetsterm vectors API可以检索存储的任何内容。

警告

使用with_positions_offsets 将会是字段的索引大小增加一倍

2.添加文档(索引文档)

PUT /ga_comment/_doc/334d318bc7c3e16e2afc
{
"account_id" : 6,
"account_name" : "小远医生",
"comment_time" : 1607319217,
"content" : "医生胃炎阴虚体寒的人能吃吗",
"pull_time" : 1607949478,
"create_time" : 1607949478587,
"delete_time" : 0,
"group_id" : 5,
"id" : 1058,
"es_id" : "334d318bc7c3e16e2afc",
"is_delete" : 0,
"is_hot" : 0,
"is_top" : 0,
"is_reply" : 0,
"nickname" : "",
"avatar" : "",
"open_comment_id" : "@9VwRgveUCc4qanugYsg0GM783GXqPvCBP5Z5rgukKVQSafj960zdRmYqig357zEBTFr5LHQ3WGpPbo89jxJc5Q==",
"open_video_id" : "@9VwRgveUCc4qanugYsg0GM783GXqPvyBP5B1qQ2gKVEQaPf960zdRmYqig357zEBHfj8y4SPElMrTSLJxMRX+Q==",
"open_id" : "aa2f1e64-5ebd-42a5-85c9-b58cb71e6a61",
"platform_code" : "douyin",
"post_status" : 0,
"role" : 0,
"reply_comment_id" : "",
"reply_time" : 0,
"reply_nickname" : "",
"reply_open_id" : "",
"total_like" : 2,
"total_reply_comment" : 3,
"update_time" : 1607949478,
"user_id" : 0,
"video_id" : 213,
"video_title" : "经常跑厕所,这个是你#脾胃虚弱的表现,可以试试这个方法",
"tag" : null
}

GET ga_comment_alias/_doc/334d318bc7c3e16e2afc 查询id文档

3-1.查询某条文档的某个字段(如图字段名称是text)的分词列表及统计

GET /ga_comment/_termvectors/_termvectors/334d318bc7c3e16e2afc
{
"fields" : ["content"],
"term_statistics" : true,
"filter": {
"max_num_terms": 5,
"min_word_length": 2
}
}
#响应
{
"_index" : "ga_comment",
"_type" : "_doc",
"_id" : "334d318bc7c3e16e2afc",
"_version" : 1,
"found" : true,
"took" : 0,
"term_vectors" : {
"content" : {
"field_statistics" : {
"sum_doc_freq" : 102,
"doc_count" : 19,
"sum_ttf" : 108
},
"terms" : {
"医生" : {
"doc_freq" : 1,
"ttf" : 1,
"term_freq" : 1,
"score" : 3.3025851
},
"的人" : {
"doc_freq" : 1,
"ttf" : 1,
"term_freq" : 1,
"score" : 3.3025851
},
"胃炎" : {
"doc_freq" : 1,
"ttf" : 1,
"term_freq" : 1,
"score" : 3.3025851
},
"能吃" : {
"doc_freq" : 3,
"ttf" : 3,
"term_freq" : 1,
"score" : 2.609438
},
"阴虚" : {
"doc_freq" : 1,
"ttf" : 1,
"term_freq" : 1,
"score" : 3.3025851
}
}
}
}
}

doc_freq 索引中有几个记录出现 (出现过该次的文档个数)

ttf 该词在全部记录中出现的次数(索引中关键词出现次数)

term_freq 在当前文档词的频率

tokens:position位置、start_offset开始的偏移值、end_offset结束的偏移值

3-2.查询动态文本分词

GET /ga_comment/_termvectors
{
"doc" : {
"content" : "经常跑厕所,这个是你#脾胃虚弱的表现,可以试试这个方法"
},
"term_statistics": true,
"field_statistics": true,
"positions": false,
"offsets": false
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-termvectors.html#docs-termvectors-terms-filtering

terms filter(取最多词频的前3个词)

max_num_terms 最大的词条数目

min_term_freq 最小的词频,比如忽略那些在字段中出现次数小于一定值的词条。

max_term_freq 最大的词频

min_doc_freq 最小的文档频率,比如忽略那些在文档中出现次数小于一定的值的词条

max_doc_freq 最大的文档频率

min_word_length 忽略的词的最小长度

max_word_length 忽略的词的最大长度

  1. 在多文档中搜索关键词词频

文档已存在时

不同索引的多个文档

POST /ga_comment/_mtermvectors
{
"docs": [
{
"_id": "2",
"fields": [
"message"
],
"term_statistics": true
},
{
"_id": "1"
}
]
}

同索引中多个文档

go demo https://github.com/olivere/elastic/blob/release-branch.v7/mtermvectors_test.go

POST /ga_comment/_mtermvectors
{
"ids": [
"334d318bc7c3e16e2afc",
"eb9a86ecaf30855e235b"
],
"parameters": {
"fields": [
"content"
],
"filter": {
"max_num_terms": 5,
"min_word_length": 2
},
"term_statistics": true
}
}

索引不存在(虚拟的)的多个文档

POST /_mtermvectors
{
"docs": [
{
"_index": "ga_comment",
"doc" : {
"message" : "test test test"
}
},
{
"_index": "ga_comment",
"doc" : {
"message" : "Another test ..."
}
}
]
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-termvectors.html

https://blog.csdn.net/h_sn9999/article/details/102834034?utm_medium=distribute.wap_relevant.none-task-blog-baidulandingword-6

Elasticsearch-92-查询term vectors词条向量信息

https://zhouze-java.github.io/2019/01/18/Elasticsearch-92-%E6%9F%A5%E8%AF%A2term-vectors%E8%AF%8D%E6%9D%A1%E5%90%91%E9%87%8F%E4%BF%A1%E6%81%AF/

Elasticsearch词频统计实现与原理解读

经实践,只是返回了在哪几个文档中出现了关键词,获取不到词频

0、实战问题

有了分词,开发中会遇到,某个索引的文档集合中,共有多少XX关键词?

这就引发出了词频统计的问题。

社区问题:

中文分词后能否统计索引词频

初学者,想做一个简单的论坛检索和热词分析的应用,IK分词后能否将分好的索引词出现频率排序。这样可以形成一个大致的热点词汇范围。

我知道单条index的话可以用termvectors做这个事情,要是上万条index能做吗?多谢!

1、创建索引

1DELETE message_index
2PUT message_index
3{
4 "mappings": {
5 "_doc":{
6 "properties":{
7 "message": {
8 "analyzer": "ik_smart",
9 "term_vector": "with_positions_offsets",
10 "boost": 8,
11 "type": "text",
12 "fielddata":"true"
13 }
14 }
15 }
16 }
17}

2、导入数据

1POST message_index/_doc/1
2{
3 "message":"沉溺于「轻易获得高成就感」的事情:有意无意地寻求用很小付出获得很大「回报」的偏方,哪怕回报是虚拟的"
4}
5POST message_index/_doc/2
6{
7 "message":"过度追求“短期回报”可以先思考这样一个问题:为什么玩王者荣耀沉溺我们总是停不下来回报"
8}
9POST message_index/_doc/3
10{
11 "message":"过度追求的努力无法带来超额的回报,就因此放弃了努力。这点在聪明人身上尤其明显。以前念本科的时候身在沉溺"
12}

3、聚合获取词频

1POST message_index/_search
2{
3 "size" : 0,
4 "aggs" : {
5 "messages" : {
6 "terms" : {
7 "size" : 10,
8 "field" : "message"
9 }
10 }
11 }
12}

4、返回结果

1{
2 "took": 4,
3 "timed_out": false,
4 "_shards": {
5 "total": 5,
6 "successful": 5,
7 "skipped": 0,
8 "failed": 0
9 },
10 "hits": {
11 "total": 3,
12 "max_score": 0,
13 "hits": []
14 },
15 "aggregations": {
16 "messages": {
17 "doc_count_error_upper_bound": 0,
18 "sum_other_doc_count": 45,
19 "buckets": [
20 {
21 "key": "回报",
22 "doc_count": 3
23 },
24 {
25 "key": "沉溺",
26 "doc_count": 2
27 },
28 {
29 "key": "的",
30 "doc_count": 2
31 },
32 {
33 "key": "过度",
34 "doc_count": 2
35 },
36 {
37 "key": "追求",
38 "doc_count": 2
39 },
40 {
41 "key": "一个",
42 "doc_count": 1
43 },
44 {
45 "key": "为什么",
46 "doc_count": 1
47 },
48 {
49 "key": "了",
50 "doc_count": 1
51 },
52 {
53 "key": "事情",
54 "doc_count": 1
55 },
56 {
57 "key": "付出",
58 "doc_count": 1
59 }
60 ]
61 }
62 }
63}

5、核心知识点解读

"fielddata":"true" 是什么?

5.1 基础认知:text类型不能用于聚合

所有字段是默认被 indexed(被索引的),这使得它们是可搜索的.可以在脚本中排序,聚合和获取字段值,但是需要不同的搜索模式.

搜索需要回答一个问题 “哪个 document(文档) 包含这个 term(词条)”,然而排序和聚合需要回答一个不同的问题 " 这个字段在这个 document(文档)中的值是多少?".

许多字段可以使用 index-time,在磁盘上的 doc_values 支持这种数据访问模式, 但是 text 字段不支持 doc_values。

5.2 docvalues和fileddata的本质区别?

docvalues 它保存某一列的数据,并索引它,用于加快聚合和排序的速度。

fileddata 它保存某一列的数据,并索引它,用于加快聚合和排序的速度。和docvalues不一样的是,fielddata保存的是text类型的字段分词后的terms,而不是保存源字段数据。

5.3 fileddata的特点

相反,text 字段使用查询时存在于内存的数据结构 fielddata.这个数据结构是第一次将字段用于聚合,排序,或者脚本时基于需求构建的。

它是通过读取磁盘上的每个 segment(片段)的整个反向索引来构建的,将 term(词条)和 document(文档)关系反转,并将结果存储在内存中,在JVM的堆中.

5.4 text字段默认关闭Fielddat的原因?

text 字段默认关闭 Fielddata Fielddata会消耗很多堆空间,尤其是加载高基数的 text 字段的时候.一旦 fielddata 加载到堆中,它在 segment(片段)中的生命周期还是存在的.

此外,加载 fielddata 是一件非常昂贵的过程,会导致用户体验到延迟的感觉.这就是为什么 fielddata 默认关闭.

如果你尝试对文本字段上的脚本进行排序,访问值,你会看到此异常:

5.5 fielddata的打开方式?

以下ES6.2.X验证ok。

1PUT my_index/_mapping/_doc
2{
3 "properties": {
4 "my_field": {
5 "type": "text",
6 "fielddata": true
7 }
8 }
9}

参考:

http://t.cn/R3MzYfZ

http://t.cn/R3MzHkJ

通透讲解:http://t.cn/R3MzRiz

fielddata中文:http://t.cn/R3MznOe

fielddata英文:http://t.cn/R3Mz3eN

https://cloud.tencent.com/developer/article/1166441

POST /ga_comment_20201207_6/_mtermvectors
{
"ids": [
"73644f2427ac08a47295",
"26a34713c56ff82658cb"
],
"parameters": {
"fields": [
"content"
],
"filter": {
"max_num_terms": 5,
"min_word_length": 2
},
"term_statistics": true
}
}
GET /ga_comment_20201207_6/_termvectors/73644f2427ac08a47295
{
"fields" : ["content"],
"term_statistics" : true,
"filter": {
"max_num_terms": 5,
"min_word_length": 2
}
}

3858943b3bb20fc0256cafc13066004d.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值