elasticsearch应用场景,elasticsearch 应用

http://www.itjxue.com  2023-01-20 00:47  来源:未知  点击次数: 

elasticsearch之七search搜索详解

query phase

一次请求要打到所有shard的一个replica/primary上去,如果每个shard都有多个replica,那么同时并发过来的搜索请求可以同时打到其他的replica上去

search的参数都是类似http请求头中的字符串参数提供搜索条件的。

GET [/index_name/type_name/]_search[?parameter_name=parameter_value...]

解释

took:耗费了几毫秒

timed_out:是否超时,这里是没有

_shards:到几个分片搜索,成功几个,跳过几个,失败几个。

hits.total:查询结果的数量,3个document

hits.max_score:score的含义,就是document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高

hits.hits:包含了匹配搜索的document的所有详细数据

与http请求传参类似

类比sql: select * from book where name like ’ %java%’ order by price desc

timeout参数:是超时时长定义。代表每个节点上的每个shard执行搜索时最多耗时多久。不会影响响应的正常返回。只会影响返回响应中的数据数量。

如:索引a中,有10亿数据。存储在5个shard中,假设每个shard中2亿数据,执行全数据搜索的时候,需要耗时1000毫秒。定义timeout为10毫秒,代表的是shard执行10毫秒,搜索出多少数据,直接返回。

GET /book/_search?timeout=10ms

全局设置:配置文件中设置 search.default_search_timeout:100ms。默认不超时。

所谓的multi-index就是从多个index中搜索数据。相对使用较少,只有在复合数据搜索的时候,可能出现。一般来说,如果真使用复合数据搜索,都会使用_all。

应用场景:生产环境log索引可以按照日期分开。

log_to_es_20190910

log_to_es_20190911

log_to_es_20180910

默认情况下,Elasticsearch搜索返回结果是10条数据。从第0条开始查询。

+/-搜索

+ :和不定义符号含义一样,就是搜索指定的字段中包含key words的数据

- : 与+符号含义相反,就是搜索指定的字段中不包含key words的数据

根据相关度评分倒排序,所以分页过深,协调节点会将大量数据聚合分析。

GET /book/_search?q=name:java

GET /book/_search?q=+name:java

GET /book/_search?q=-name:java

直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来。我们在进行中搜索的时候,难道是对document中的每一个field都进行一次搜索吗?不是的。

es中_all元数据。建立索引的时候,插入一条docunment,es会将所有的field值经行全量分词,把这些分词,放到_all field中。在搜索的时候,没有指定field,就在_all搜索。

举例

_all : jack,123@qq.com ,beijing 作为这一条document的_all field的值,同时进行分词后建立对应的倒排索引

DSL - Domain Specified Language , 特殊领域的语言。

请求参数是请求体传递的。在Elasticsearch中,请求体的字符集默认为UTF-8。

query string 后边的参数原来越多,搜索条件越来越复杂,不能满足需求。

DSL:Domain Specified Language,特定领域的语言

es特有的搜索语言,可在请求体中携带搜索条件,功能强大。

查询全部 GET /book/_search

排序 GET /book/_search?sort=price:desc

分页查询 GET /book/_search?size=10from=0

指定返回字段 GET /book/ _search? _source=name,studymodel

通过组合以上各种类型查询,实现复杂查询。

搜索需求:title必须包含elasticsearch,content可以包含elasticsearch也可以不包含,author_id必须不为111

初始数据:

搜索:

返回:

更复杂的搜索需求:

select * from test_index where name='tom' or (hired =true and (personality ='good' and rude != true ))

重新创建book索引

插入数据

搜索

relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度。

Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法。TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)

Term frequency :搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关。

举例:搜索请求:hello world

doc1 : hello you and me,and world is very good.

doc2 : hello,how are you

Inverse document frequency :搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的次数越多,就越不相关.

举例:搜索请求:hello world

doc1 : hello ,today is very good

doc2 : hi world ,how are you

整个index中1亿条数据。hello的document 1000个,有world的document 有100个。

doc2 更相关

Field-length norm :field长度,field越长,相关度越弱

举例:搜索请求:hello world

doc1 : {"title":"hello article","content ":"balabalabal 1万个"}

doc2 : {"title":"my article","content ":"balabalabal 1万个,world"}

返回

搜索的时候,要依靠倒排索引;排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是doc values

在建立索引的时候,一方面会建立倒排索引,以供搜索用;一方面会建立正排索引,也就是doc values,以供排序,聚合,过滤等操作使用

doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高;如果内存不足够,os会将其写入磁盘上

倒排索引

doc1: hello world you and me

doc2: hi, world, how are you

搜索时:

hello you -- hello, you

hello -- doc1

you -- doc1,doc2

doc1: hello world you and me

doc2: hi, world, how are you

sort by 出现问题

正排索引

doc1: { "name": "jack", "age": 27 }

doc2: { "name": "tom", "age": 30 }

一般搜索,如果不加from和size,就默认搜索前10条,按照_score排序

短语检索。要求查询条件必须和具体数据完全匹配才算搜索结果。其特征是:1-搜索条件不做任何分词解析;2-在搜索字段对应的倒排索引(正排索引)中进行精确匹配,不再是简单的全文检索。

决定了哪些shard会被用来执行搜索操作

_primary, _primary_first, _local, _only_node:xyz, _prefer_node:xyz, _shards:2,3

bouncing results问题,两个document排序,field值相同;不同的shard上,可能排序不同;每次请求轮询打到不同的replica shard上;每次页面上看到的搜索结果的排序都不一样。这就是bouncing result,也就是跳跃的结果。

搜索的时候,是轮询将搜索请求发送到每一个replica shard(primary shard),但是在不同的shard上,可能document的排序不同

解决方案就是将preference设置为一个字符串,比如说user_id,让每个user每次搜索的时候,都使用同一个replica shard去执行,就不会看到bouncing results了

主要就是限定在一定时间内,将部分获取到的数据直接返回,避免查询耗时过长

document文档路由,_id路由,routing=user_id,这样的话可以让同一个user对应的数据到一个shard上去

default:query_then_fetch

dfs_query_then_fetch,可以提升revelance sort精准度

ElasticSearch海量数据使用简述

应用场景当中经常会遇到模糊查询或多条件匹配查询,数据量较小的情况下通过简单的数据库模糊查询是可以解决的,但是对于数据量庞大的情况,数据库模糊查询就会出现性能问题。这种情况下的一种解决方案就是根据查询内容构建反向索引,借助搜索引擎进行查询,提升查询性能。

目前使用比较多的分布式搜索引擎是ElasticSearch。那么项目中如何使用ES?如何保证ES的数据更新?下面简单做个描述。

Elasticsearch使用可以简单分为两个阶段。数据初始化阶段、数据更新阶段。

数据初始化阶段。数据初始化常见的方式如下:

一、通过应用程序手动将数据库中的数据,调用ES接口API插入ES索引库中。

二、同过数据迁移工具将数据初始化到ES数据库。目前常用的ES同步工具有logstash-input-jdbc、DataX。通过同步迁移工具可以全量将数据库数据初始化到ES索引库中。

数据更新阶段。数据更新阶段常见的处理方式如下:

一、通过应用服务直接调用ES更新接口。这种方式实现比较简单但是对业务侵入性比较大。

二、对于实时性要求不高的可以采用定时任务监控数据表变化然后调用ES接口实现数据更新。

三、业务应用中通过发送消息异步更新数据。

四、通过DataX同步工具定时将修改的数据同步到ES库中。

上述是ElasticSearch使用的简单描述。使用的关键还是数据库与ES间的数据同步。能否用的好关键也是数据间的同步。

Elasticsearch——search搜索入门

Search执行的时候分为两个运行步骤:

相关性算分在shard与shard之间是相互独立的,也就意味着同一个Term的IDF等值在不同shard上是不同的,文档的相关性算分和它所处的shard相关,在文档数量不多时,会导致相关性算分严重不准的情况发生。

解决思路有两个:

es默认会采用相关性算分排序,用户可以通过设定sorting参数来自行设定排序规则

Fielddata VS DocValues

Fielddata默认是关闭的,可以通过如下api开启:

DocValues默认是启用的,可以在创建索引的时候关闭,如果后面要开启DocValues,需要做reindex操作。

可以通过该字段获取fielddata获取DocValues中储存的内容。

无条件搜索所有

解释 :

与http请求传参类似

默认情况下,es的timeout机制是关闭的。比如,如果你的搜索特别慢,每个shard都要花好几分钟才能查询出来所有的数据,那么你的搜索请求也会等待好几分钟才会返回。

我们有些应用系统对时间是非常敏感的,比如说电商网站,你不能让用户等10分钟,才能等到一次搜索请求的结果。

timeout机制 :指定每个shard只能在timeout时间范围内,将搜索到的部分数据(也可能是全部数据),直接返回给客户端,而不是等到所有的数据全部搜索出来以后再返回。确保一次搜索请求可以在用户指定的timeout时长内完成,为一些时间敏感的搜索应用提供良好的支持。

全局设置:配置文件中设置 search.default_search_timeout:100ms 。该设置不常用。

如何一次性搜索多个index和多个type下的数据

应用场景:生产环境log索引可以按照日期分开。

es提供了3种方式来解决分页与遍历的问题:

最常用的分页方案:

如果每页展示 5 条结果,可以用下面方式请求得到 1 到 3 页的结果:

深度分页是一个经典问题:在数据分片存储的情况下,如何获取前1000条数据?

除了会遇到效率上的问题,还有一个无法解决的问题是es目前支持最大的skip值是max_result_window默认为10000,也就是说当from+size max_result_window时,es将返回错误。

解决方案:

问题描述:比如当客户线上的es数据出现问题,当分页到几百页的时候,es无法返回数据,此时为了恢复正常使用,我们可以采用紧急规避的方式,就是将max_result_window的值调至50000。

对于上面这种解决方案只是暂时解决问题,当es的使用越来越多时,数据量越来越大,深度分页的场景越来越复杂时,可以使用另一种分页方式scroll。

什么是deep paging

遍历文档集的api,以快照的方式来避免深度分页的问题。

直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来。我们在进行中搜索的时候,难道是对document中的每一个field都进行一次搜索吗?不是的。

es中all元数据。建立索引的时候,插入一条document,es会将所有的field值经行全量分词,把这些分词,放到all field中。在搜索的时候,没有指定field,就在_all搜索。

举例

_all : jack,123@qq.com ,beijing

参考:

(责任编辑:IT教学网)

更多

推荐windows vista文章