ElasticSearch 集群架构与搜索深入理解(下)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ElasticSearch 集群架构与搜索深入理解

分词的结果是:


{ 
"tokens": [ 
{ 
"token": "hello", 
"start_offset": 0, 
"end_offset": 5, 
"type": "<ALPHANUM>", 
"position": 0 
}, 
{ 
"token": "world", 
"start_offset": 6, 
"end_offset": 11, 
"type": "<ALPHANUM>", 
"position": 1 
}, 
{ 
"token": "java", 
"start_offset": 13, 
"end_offset": 17, 
"type": "<ALPHANUM>", 
"position": 2 
}, 
{ 
"token": "spark", 
"start_offset": 18, 
"end_offset": 23, 
"type": "<ALPHANUM>", 
"position": 3 
} 
] 
} 


从上述结果中,可以看到。ES在做分词的时候,除了将数据切分外,还会保留一个position。position代表的是这个词在整个数据中的下标。当ES执行matchphrase搜索的时候,首先将搜索条件hello world分词为hello和world。然后在倒排索引中检索数据,如果hello和world都在某个document的某个field出现时,那么检查这两个匹配到的单词的position是否是连续的,如果是连续的,代表匹配成功,如果是不连续的,则匹配失败。


**-2). match phrase搜索参数 -- slop **


在做搜索操作的是,如果搜索参数是hello spark。而ES中存储的数据是hello world, java spark。那么使用match phrase则无法搜索到。在这个时候,可以使用match来解决这个问题。但是,当我们需要在搜索的结果中,做一个特殊的要求:hello和spark两个单词距离越近,document在结果集合中排序越靠前,这个时候再使用match则未必能得到想要的结果。


ES的搜索中,对match phrase提供了参数slop。slop代表match phrase短语搜索的时候,单词最多移动多少次,可以实现数据匹配。在所有匹配结果中,多个单词距离越近,相关度评分越高,排序越靠前。


这种使用slop参数的match phrase搜索,就称为近似匹配(proximity search)


如:


数据为: hello world, java spark


搜索为: match phrase : hello spark。


slop为: 3 (代表单词最多移动3次。)


执行短语搜索的时候,将条件hello spark分词为hello和spark两个单词。并

且连续。


hello spark


接下来,可以根据slop参数执行单词的移动。


下标 0 1 2 3
doc hello world java spark
搜索 hello spark
移动 hello spark
移动2 hello spark


匹配成功,不需要移动第三次即可匹配。


如果:


数据为: hello world, java spark


搜索为: match phrase : spark hello。


slop为: 5 (代表单词最多移动5次。)执行短语搜索的时候,将条件hello spark分词为hello和spark两个单词。并且连续。


spark hello


接下来,可以根据slop参数执行单词的移动。


下标 : 0 1 2 3


doc : hello world java spark


搜索 : spark hello

移动1: spark/hello

移动2: hello spark

移动3: hello spark

移动4: hello spark


匹配成功,不需要移动第五次即可匹配。


如果当slop移动次数使用完毕,还没有匹配成功,则无搜索结果。如果使用中文分词,则


移动次数更加复杂,因为中文词语有重叠情况,很难计算具体次数,需要多次尝试才行。


测试案例:


英文:


GET _analyze 
{ 
"text": "hello world, java spark", 
"analyzer": "standard" 
} 
POST /test_a/_doc/3 
{ 
"f" : "hello world, java spark" 
} 
GET /test_a/_search 
{ 
"query": { 
"match_phrase": { 
"f" : { 
"query": "hello spark", 
"slop" : 2 
} 
} 
} 
}
GET /test_a/_search 
{ 
"query": { 
"match_phrase": { 
"f" : { 
"query": "spark hello", 
"slop" : 4 
} 
} 
} 
} 


**中文: **


GET _analyze 
{ 
"text": "中国,一个世界上最强的国家", 
"analyzer": "ik_max_word" 
} 
POST /test_a/_doc/1 
{ 
"f" : "中国,一个世界上最强的国家" 
} 
GET /test_a/_search 
{ 
"query": { 
"match_phrase": { 
"f" : { 
"query": "中国最强", 
"slop" : 5 
} 
} 
} 
} 
GET /test_a/_search 
{ 
"query": { 
"match_phrase": {
"f" : { 
"query": "最强中国", 
"slop" : 9 
} 
} 
} 
}

六.经验分享


使用match和proximity search实现召回率和精准度平衡。


召回率:召回率就是搜索结果比率,如:索引A中有100个document,搜索时返回多少个document,就是召回率(recall)。


精准度:就是搜索结果的准确率,如:搜索条件为hello java,在搜索结果中尽可能让短语匹配和hello java离的近的结果排序靠前,就是精准度 (precision)。


如果在搜索的时候,只使用match phrase语法,会导致召回率底下,因为搜索

结果中必须包含短语(包括proximity search)。


如果在搜索的时候,只使用match语法,会导致精准度底下,因为搜索结果排

序是根据相关度分数算法计算得到。


那么如果需要在结果中兼顾召回率和精准度的时候,就需要将match和

proximity search混合使用,来得到搜索结果。


测试案例:


POST /test_a/_doc/3
{
"f" : "hello, java is very good, spark is also very good"
}
POST /test_a/_doc/4
{
"f" : "java and spark, development language "
}
POST /test_a/_doc/5
{ "f" : "Java Spark is a fast and general‐purpose cluster computing system. I t provides high‐level APIs in Java, Scala, Python and R, and an optimized engi ne that supports general execution graphs."
}
POST /test_a/_doc/6
{
"f" : "java spark and, development language "
}
GET /test_a/_search
{
"query": {
"match": {
"f": "java spark"
}
}
}
GET /test_a/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"f": "java spark"
}
}
],
"should": [
{
"match_phrase": {
"f": {
"query": "java spark",
"slop" : 50
}
}
}
]
}
}
}

七、前缀搜索 prefix search


使用前缀匹配实现搜索能力。通常针对keyword类型字段,也就是不分词的字段。


语法:


GET /test_a/_search 
{ 
"query": { 
"prefix": { 
"f.keyword": { 
"value": "J" 
} 
} 
} 
} 


**注意:针对前缀搜索,是对keyword类型字段而言。而keyword类型字段数据大小写敏感。 **


前缀搜索效率比较低。前缀搜索不会计算相关度分数。前缀越短,效率越低。


如果使用前缀搜索,建议使用长前缀。因为前缀搜索需要扫描完整的索引内容,所以前缀越长,相对效率越高。


八、通配符搜索


ES中也有通配符。但是和java还有数据库不太一样。通配符可以在倒排索引中使用,也可以在keyword类型字段中使用。


常用通配符:

? - 一个任意字符


* - 0~n个任意字符


GET /test_a/_search 
{ 
"query": { 
"wildcard": { 
"f.keyword": { 
"value": "?e*o*" 
} 
}
} 
}


性能也很低,也是需要扫描完整的索引。不推荐使用。


九、正则搜索


ES支持正则表达式。可以在倒排索引或keyword类型字段中使用。 常用符号:

[] - 范围,如: [0-9]是0~9的范围数字


. - 一个字符


+ - 前面的表达式可以出现多次。


GET /test_a/_search 
{ 
"query": { 
"regexp" : { 
"f.keyword" : "[A‐z].+" 
} 
} 
} 


性能也很低,需要扫描完整索引。


十、搜索推荐


搜索推荐: search as your type, 搜索提示。如:索引中有若干数据以“hello”开头,那么在输入hello的时候,推荐相关信息。(类似百度输入框)


语法:


GET /test_a/_search 
{ 
"query": { 
"match_phrase_prefix": { 
"f": { 
"query": "java s", 
"slop" : 10, 
"max_expansions": 10 
} 
} 
} 
}


其原理和match phrase类似,是先使用match匹配term数据(java),然后在指定的slop移动次数范围内,前缀匹配(s),max_expansions是用于指定prefix 最多匹配多少个term(单词),超过这个数量就不再匹配了。


这种语法的限制是,只有最后一个term会执行前缀搜索。

执行性能很差,毕竟最后一个term是需要扫描所有符合slop要求的倒排索引的 term。


因为效率较低,如果必须使用,则一定要使用参数max_expansions。


十一、fuzzy模糊搜索技术


搜索的时候,可能搜索条件文本输入错误,如:hello world -> hello word。


这种拼写错误还是很常见的。fuzzy技术就是用于解决错误拼写的(在英文中很有效,在中文中几乎无效。)。其中fuzziness代表value的值word可以修改多少个字母来进行拼写错误的纠正(修改字母的数量包含字母变更,增加或减少字母。)。f代表要搜索的字段名称。


GET /test_a/_search 
{ 
"query": { 
"fuzzy": { 
"f" : { 
"value" : "word", 
"fuzziness": 2 
} 
} 
} 
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
15天前
|
存储 监控 安全
Elasticsearch 集群
【11月更文挑战第3天】
94 54
|
18天前
|
人工智能 云计算 网络架构
阿里云引领智算集群网络架构的新一轮变革
11月8日~10日在江苏张家港召开的CCF ChinaNet(即中国网络大会)上,众多院士、教授和业界技术领袖齐聚一堂,畅谈网络未来的发展方向,聚焦智算集群网络的创新变革。
阿里云引领智算集群网络架构的新一轮变革
|
19天前
|
负载均衡 Dubbo 算法
集群容错架构设计
集群容错架构设计
26 1
集群容错架构设计
|
7天前
|
缓存 监控 Java
Elasticsearch集群JVM调优
Elasticsearch集群JVM调优
24 5
|
11天前
|
监控 API 索引
Elasticsearch集群健康检查
【11月更文挑战第4天】
27 3
|
17天前
|
存储 缓存 固态存储
Elasticsearch高性能搜索
【11月更文挑战第1天】
33 6
|
17天前
|
人工智能 运维 网络架构
阿里云引领智算集群网络架构的新一轮变革
11月8日至10日,CCF ChinaNet(中国网络大会)在江苏张家港召开,众多院士、教授和技术领袖共聚一堂,探讨网络未来发展方向。阿里云研发副总裁蔡德忠发表主题演讲,展望智算技术发展趋势,提出智算网络架构变革的新思路,发布高通量以太网协议和ENode+超节点系统规划,引起广泛关注。阿里云HPN7.0引领智算以太网生态蓬勃发展,成为业界标杆。未来,X10规模的智算集群将面临新的挑战,Ethernet将成为主流方案,推动Scale up与Scale out的融合架构,提升整体系统性能。
|
15天前
|
存储 缓存 NoSQL
【赵渝强老师】Memcached集群的架构
Memcached 是一个高性能的分布式内存对象缓存系统,通过在内存中维护一个巨大的 Hash 表来存储各种格式的数据,如图像、视频、文件及数据库检索结果等。它主要用于减轻数据库压力,提高网站系统的性能。Memcached 不支持数据持久化,因此仅作为缓存技术使用。其数据分布式存储由客户端应用程序实现,而非服务端。
【赵渝强老师】Memcached集群的架构
|
16天前
|
API 索引
Elasticsearch实时搜索
【11月更文挑战第2天】
30 1
|
16天前
|
存储 索引
Elasticsearch分布式架构
【11月更文挑战第2天】
23 1
下一篇
无影云桌面