「es创建索引java」es创建索引模板

博主:adminadmin 2022-12-09 13:33:07 70

本篇文章给大家谈谈es创建索引java,以及es创建索引模板对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

es使用与原理2 -- scoll技术,bouncing results,零停机重建索引等等

默认情况下,是按照_score降序排序的,我们也可以定制排序规则

Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法

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

如:搜索请求:hello world

doc1:hello you, and world is very good

doc2:hello, how are you

doc1 肯定比doc2的评分高,因为hello world都在doc1中出现了。

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

搜索请求:hello world

doc1:hello, today is very good

doc2:hi world, how are you

比如说,在index中有1万条document,hello这个单词在所有的document中,一共出现了1000次;world这个单词在所有的document中,一共出现了100次

那最终的结果肯定是 word的得分所占比更高

关于_score,ES还有一条规则。

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

搜索请求:hello world

doc1:{ "title": "hello article", "content": "babaaba 1万个单词" }

doc2:{ "title": "my article", "content": "blablabala 1万个单词,hi world" }

hello world在整个index中出现的次数是一样多的。最终 doc1得分更高

搜索的时候,要依靠倒排索引;排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是doc values,doc values 也可以供排序,聚合,过滤等操作使用。doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高;如果内存不足够,os会将其写入磁盘上

正排索引如下:

倒排索引不可变的好处

想象一下有两个文档有同样值的时间戳字段,搜索结果用 timestamp 字段来排序。 由于搜索请求是在所有有效的分片副本间轮询的,那就有可能发生主分片处理请求时,这两个文档是一种顺序, 而副本分片处理请求时又是另一种顺序。

这就是所谓的 bouncing results 问题: 每次用户刷新页面,搜索结果表现是不同的顺序。 让同一个用户始终使用同一个分片,这样可以避免这种问题, 可以设置 preference 参数为一个特定的任意值比如用户会话ID来解决。

如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scoll滚动查询,一批一批的查,直到所有数据都查询完处理完。

scoll,看起来挺像分页的,但是其实使用场景不一样。分页主要是用来一页一页搜索,给用户看的;scoll主要是用来一批一批检索数据,让系统进行处理的

使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来

scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的

采用基于_doc进行排序的方式,性能较高

每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了

获得的结果会有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id

1 创建索引

2 修改索引

3 删除索引

lucene是没有type的概念的,在document中,实际上将type作为一个document的field来存储,即_type,es通过_type来进行type的过滤和筛选

一个index中的多个type,实际上是放在一起存储的,因此一个index下,不能有多个type重名,而类型或者其他设置不同的,因为那样是无法处理的

比如

底层存储是这样的

将类似结构的type放在一个index下,这些type应该有多个field是相同的

假如说,你将两个type的field完全不同,放在一个index下,那么就每条数据都d会有大量field在底层的lucene中是空值,会有严重的性能问题

1、定制dynamic策略

true:遇到陌生字段,就进行dynamic mapping

false:遇到陌生字段,就忽略

strict:遇到陌生字段,就报错

2、定制自己的dynamic mapping template(type level)

上面的设置是/my_index/my_type 的字段,如果是以_en结尾的,那么就自动映射为string类型

一个field的设置是不能被修改的,如果要修改一个Field,那么应该重新按照新的mapping,建立一个index,然后将数据批量查询出来,重新用bulk api写入index中。

批量查询的时候,建议采用scroll api,并且采用多线程并发的方式来reindex数据,每次scoll就查询指定日期的一段数据,交给一个线程即可。

(1)一开始,依靠dynamic mapping,插入数据,但是不小心有些数据是2017-01-01这种日期格式的,所以title这种field被自动映射为了date类型,实际上业务认为它应该是string类型的

(2)当后期向索引中加入string类型的title值的时候,就会报错

(3)如果此时想修改title的类型,是不可能的

(4)此时,唯一的办法,就是进行reindex,也就是说,重新建立一个索引,将旧索引的数据查询出来,再导入新索引

(5)如果说旧索引的名字,是old_index,新索引的名字是new_index,终端java应用,已经在使用old_index在操作了,难道还要去停止java应用,修改使用的index为new_index,才重新启动java应用吗?这个过程中,就会导致java应用停机,可用性降低

(6)所以说,给java应用一个别名,这个别名是指向旧索引的,java应用先用着,java应用先用goods_index alias来操作,此时实际指向的是旧的my_index

(7)新建一个index,调整其title的类型为string

(8)使用scroll api将数据批量查询出来

(9)采用bulk api将scoll查出来的一批数据,批量写入新索引

(10)反复循环8~9,查询一批又一批的数据出来,采取bulk api将每一批数据批量写入新索引

(11)将goods_index alias切换到my_index_new上去,java应用会直接通过index别名使用新的索引中的数据,java应用程序不需要停机,零提交,高可用

(12)直接通过goods_index别名来查询,是否ok

现有流程的问题,每次都必须等待fsync将segment刷入磁盘,才能将segment打开供search使用,这样的话,从一个document写入,到它可以被搜索,可能会超过1分钟!!!这就不是近实时的搜索了!!!主要瓶颈在于fsync实际发生磁盘IO写数据进磁盘,是很耗时的。

java 操作es多索引查询的时候,可不可以首先指定一个索引的查询条件,然后在进行多索引查询?

你建立的是联合索引,按照索引中字段顺序使用才会最大化的发挥索引的作用。

索引的建立不需要看主键有几个字段,而是看你的查询条件经常用到哪几列,

如果经常同时用到好几列,就可以在这几列上建联合索引,

如果查询条件经常都只是用到某一个字段,只需要在该字段上建一个单独索引

es 创建动态索引(二)

上一篇文章

es 创建动态索引(一) ,通过el表达式 修改 @Document 里 indexName 值,实现 es 动态索引。

后来使用时候发现如果实体类上有注解@Field

例如

springboot 启动时候创建的mapping为:

而这种动态的方式为创建的mapping为:

不一样,所以就想看看 启动时候是怎么创建的。使用同样的方式创建就可以。

AbstractElasticsearchRepository.java 中,

构造函数初始时候会去判断要不要创建index和mapping

这个值在@Document中,默认值为true

如果要创建就调用 创建index 和 put mapping方法

而创建和映射是调用elasticsearchOperations 的方法实现的

而它的实现类 即是ElasticsearchTemplate

时序图如下:

所以我们可以在保存数据时候,判断索引是否存在,不存在创建和设置mapping

亲测 ok 了。

而之前的时间粒度为秒 来创建动态索引 太细了。

可能索引创建和mapping ok 了,但是保存时候 到了下一秒,es 自己就会去创建 。

所以为了测试 将时间细分到 分来测试。

测试结果如下,索引 和 mapping都没问题。

ElasticSearch索引模板

在ElasticSearch中创建索引时,可以为创建的索引指定索引的属性设定,映射关系,别名等操作,然而,每次创建索引都要指定这些参数比较麻烦。ES提供了一种方法可以在索引创建时自动为索引进行设置,这种方法叫做索引模板。

上面这段是使用ES RestAPI创建索引模板:

index_patterns :用来指定适用于该模板的索引名称,一般可以使用前缀加 * 的方法来进行设定。可以设置多个。

order :可以同时指定多个模板,在存在冲突的情况下,order值高的可以覆盖order值低的模板。如果 order 值相同,则情况不可预测。

setting , mapping , aliases :与索引设定中的一致。

version :可以选择为索引模板添加版本号。

ES中存在多个模板匹配到同一个索引的情况。这时候,产生的索引会将两者的配置合并产生新的索引设置内容。如果存在内容冲突的情况,使用 order 值进行解决,详情见上一节的描述。

以下面为例:

创建一个新的索引:

结果可见, High 的类型被覆盖成了 text 类型。

如果将test_temp1的 order 值调成0会怎么样呢。笔者试了很多次, High 的值一直保持 integer 的类型。而文档中描述这种情况是不可预知的。

当一个事先未设置的字段被加入到一个索引中时,ES会怎样处理呢?索引提供了 dynamic 字段来提供不同的处理策略。 dynamic 字段有3个可选值, true , false 以及 strict

true : 这是 dynamic 字段的默认值,在这种情况,ES会接收字段并根据其类型进行自动映射。

false : 这个字段关闭了动态mapping的功能,如果文档中包含没有事先mapping的字段,这个字段会被存储,但是在搜索时是无法被搜索到的。我们可以通过修改mapping,然后使用 _update_by_query API,使得该字段可以被索引到。

strict : 严格mapping,如果有不符合映射关系的字段,索引操作会失败。

上文提到,ES检测到字符串类型时会自动对其进行日期类型检测。这个行为可以在索引mapping中开启或关闭,默认是处于开启状态。可以通过将 date_detection 设置成 false 来将该功能关闭。

日期类型检测默认会匹配这样的日期格式: "yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"

用户也可以在 dynamic_date_formats 中自定义日期格式。

有一些程序会在json格式中将数字类型设置成字符串,ES可以对其进行自动识别,但是该功能默认是关闭的,需要用户手动打开。

ES还提供了动态模板这种方法来对动态识别出来的字段进行处理。

动态模板的格式如下:

其中,模板的名称可以自定义, mapping 部分则是对动态识别出来的字段进行处理。两种之间则是用来定义进行mapping的条件。这部分可能用到 match_mapping_type , match , unmatch , match_pattern , path_match , path_unmatch 。

动态模板是按顺序进行匹配的,当一个类型命中了一个模板的条件后,就不会再进行后续匹配了。

在模板已经设置的情况下,如果使用put方法设置动态模板。新的模板会覆盖原有模板。

match_mapping_type 是指的ES的json解析器解析出来的类型,由于json类型不会告诉ES一个整形类型的长度是32位还是64位,也不会告诉ES一个浮点数是单精度还是双精度,因此ES总会使用适用范围更广的类型。

用来做字段名匹配的, match 用来指定需要匹配的字段模式,而 unmatch 则用来将 match 中包含的部分不需要做动态匹配的字段剔除。

以上这段会做以下动作:将未事先指定的字符串类型自动,如果其字段名前缀是 long_ ,且后缀为 _text ,将其映射为 long 类型。

match_pattern 可以用来指定match的匹配方式,可以指定其为 regex ,这样就会以java正则匹配的方式来对字段名进行匹配。如果不指定,默认会使用简单的 wildchart 方式进行匹配。

与 match 及 unmatch 类似,区别是 path_match 和 path_unmatch 匹配的的模式是xxx.xxx.xxx,这种模式用于object属性的映射匹配。

以上将一个人的first name和last name进行组合拼成了一个全名。

动态模板有两个内置属性 {name} 和 {dynamic_type} 用来指代字段名称及其自动识别出来的类型。

以上这段,将识别出来的字符串类型的分词器设置成与其属性名相同。并且关闭了除此之外所有属性的 doc_values 。

用java怎么造es的mappings元数据

用java怎么造es的mappings元数据

Mapping,就是对索引库中索引的字段名及其数据类型进行定义,类似于关系数据库中表建立时要定义字段名及其数据类型那样,不过es的mapping比数据库灵活很多,它可以动态添加字段。一般不需要要指定mapping都可以,因为es会自动根据数据格式定义它的类型,如果你需要对某些字段添加特殊属性

关于es创建索引java和es创建索引模板的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-09,除非注明,否则均为首码项目网原创文章,转载请注明出处。