Elasticserach使用总结
前言
Elasticsearch官网doc
https://www.elastic.co/guide/en/elasticsearch/reference/6.0/getting-started.html
Spring Data Elasticsearch
https://docs.spring.io/spring-data/elasticsearch/docs/3.2.9.RELEASE/reference/html/#core.web.basic.domain-class-converter
注意
spring data Elasticsearch 与Elasticsearch版本需保持一致。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GFW9PvGT-1597631933351)(C:\Users\Waspal\Desktop\elastic\image-20200727145155149.png)]
Elasticsearch安装
安装文档
https://www.elastic.co/guide/en/elasticsearch/reference/6.0/_installation.html
注意
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iQKfTQBm-1597631933354)(C:\Users\Waspal\Desktop\elastic\image-20200727145438355.png)]
- 这两个端口一个是http协议端口一个是tcp协议端口后续使用时需要注意区分。
- 安装过程按照文档上的进行即可成功安装。
安装成功
访问9200端口即可看到自己安装的Elastic版本。
如果安装过程中安装了安全组件需要进行用户名密码登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RbxTDPUZ-1597631933356)(C:\Users\Waspal\Desktop\elastic\image-20200727145952961.png)]
Elasticsearch API使用
具体使用信息可以参考官网api 这里不再赘述。
https://www.elastic.co/guide/en/elasticsearch/reference/6.0/docs-index_.html
英文不好的可以参考对应的中文文档(建议查看英文文档)
https://www.elastic.co/guide/cn/elasticsearch/guide/current/getting-started.html(不够新)
轻量级搜索
GET /索引名称/索引类型/_search?q=字段:value
表达式搜索
GET /索引名称/索引类型/_search
{
"query" : {
"match" : {
"字段" : "value"
}
}
}
复杂搜索
GET /索引名称/索引类型/_search
{
"query" : {
"bool": { //复合查询
"must": { //相等
"match" :
"字段" : "value"
}
},
"filter": { //过滤
"range" : {
"字段" : { "gt" : 30 }
}
}
}
}
}
全文搜索
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
短语搜索
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
高亮搜索
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : { //短语匹配
"about" : "rock climbing"
}
},
"highlight": { //高亮字段
"fields" : {
"about" : {}
}
}
}
聚合分析
GET /megacorp/employee/_search
{
"aggs": { //聚合分析
"all_interests": {
"terms": { "field": "interests" }//聚合字段
}
}
}
文档更新
update
请求最简单的一种形式是接收文档的一部分作为 doc
的参数, 它只是与现有的文档进行合并。对象被合并到一起,覆盖现有的字段,增加新的字段。 例如,我们增加字段 tags
和 views
到我们的博客文章。如下所示:
POST /website/blog/1/_update
{
"doc" : { //需要更新的内容
"tags" : [ "testing" ],
"views": 0
}
}
使用脚本部分更新文档
默认脚本语言:Groovy 脚本编程
脚本可以在 update
API中用来改变 _source
的字段内容, 它在更新脚本中称为 ctx._source
。 例如,我们可以使用脚本来增加博客文章中 views
的数量:
POST /website/blog/1/_update
{
"script" : "ctx._source.views+=1"
}
我们也可以通过使用脚本给 tags
数组添加一个新的标签。在这个例子中,我们指定新的标签作为参数,而不是硬编码到脚本内部。 这使得 Elasticsearch 可以重用这个脚本,而不是每次我们想添加标签时都要对新脚本重新编译:
POST /website/blog/1/_update
{
"script" : "ctx._source.tags+=new_tag",
"params" : {
"new_tag" : "search"
}
}
获取文档并显示最后两次请求的效果:
{
"_index": "website",
"_type": "blog",
"_id": "1",
"_version": 5,
"found": true,
"_source": {
"title": "My first blog entry",
"text": "Starting to get the hang of this...",
"tags": ["testing", "search"],
"views": 1
}
}
search 标签已追加到 tags 数组中。 | |
---|---|
views 字段已递增。 |
我们甚至可以选择通过设置 ctx.op
为 delete
来删除基于其内容的文档:
POST /website/blog/1/_update
{
"script" : "ctx.op = ctx._source.views == count ? 'delete' : 'none'",
"params" : {
"count": 1
}
}
更新的文档可能尚不存在
假设我们需要在 Elasticsearch 中存储一个页面访问量计数器。 每当有用户浏览网页,我们对该页面的计数器进行累加。但是,如果它是一个新网页,我们不能确定计数器已经存在。 如果我们尝试更新一个不存在的文档,那么更新操作将会失败。
在这样的情况下,我们可以使用 upsert
参数,指定如果文档不存在就应该先创建它:
POST /website/pageviews/1/_update
{
"script" : "ctx._source.views+=1",
"upsert": {
"views": 1
}
}
我们第一次运行这个请求时, upsert
值作为新文档被索引,初始化 views
字段为 1
。 在后续的运行中,由于文档已经存在, script
更新操作将替代 upsert
进行应用,对 views
计数器进行累加。
更新和冲突
在本节的介绍中,我们说明 检索 和 重建索引 步骤的间隔越小,变更冲突的机会越小。 但是它并不能完全消除冲突的可能性。 还是有可能在 update
设法重新索引之前,来自另一进程的请求修改了文档。
为了避免数据丢失, update
API 在 检索 步骤时检索得到文档当前的 _version
号,并传递版本号到 重建索引 步骤的 index
请求。 如果另一个进程修改了处于检索和重新索引步骤之间的文档,那么 _version
号将不匹配,更新请求将会失败。
对于部分更新的很多使用场景,文档已经被改变也没有关系。 例如,如果两个进程都对页面访问量计数器进行递增操作,它们发生的先后顺序其实不太重要; 如果冲突发生了,我们唯一需要做的就是尝试再次更新。
这可以通过设置参数 retry_on_conflict
来自动完成, 这个参数规定了失败之前 update
应该重试的次数,它的默认值为 0
。
POST /website/pageviews/1/_update?retry_on_conflict=5
{
"script" : "ctx._source.views+=1",
"upsert": {
"views": 0
}
}
失败之前重试该更新5次。 | |
---|---|
在增量操作无关顺序的场景,例如递增计数器等这个方法十分有效,但是在其他情况下变更的顺序 是 非常重要的。 类似 index
API , update
API 默认采用 最终写入生效 的方案,但它也接受一个 version
参数来允许你使用 optimistic concurrency control 指定想要更新文档的版本。
取回多个文档
mget
API 要求有一个 docs
数组作为参数,每个元素包含需要检索文档的元数据, 包括 _index
、 _type
和 _id
。如果你想检索一个或者多个特定的字段,那么你可以通过 _source
参数来指定这些字段的名字:
GET /_mget
{
"docs" : [
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website ",
"_type" : "pageviews",
"_id" : 1,
"_source": "views"
}
]
}
如果想检索的数据都在相同的 _index
中(甚至相同的 _type
中),则可以在 URL 中指定默认的 /_index
或者默认的 /_index/_type
GET /website/blog/_mget
{
"docs" : [
{ "_id" : 2 },
{ "_type" : "pageviews", "_id" : 1 }
]
}
事实上,如果所有文档的 _index
和 _type
都是相同的,你可以只传一个 ids
数组,而不是整个 docs
数组:
GET /website/blog/_mget
{
"ids" : [ "2", "1" ]
}
批量操作
整个批量请求都需要由接收到请求的节点加载到内存中,因此该请求越大,其他请求所能获得的内存就越少。 批量请求的大小有一个最佳值,大于这个值,性能将不再提升,甚至会下降。 但是最佳值不是一个固定的值。它完全取决于硬件、文档的大小和复杂度、索引和搜索的负载的整体情况。
幸运的是,很容易找到这个 最佳点 :通过批量索引典型文档,并不断增加批量大小进行尝试。 当性能开始下降,那么你的批量大小就太大了。一个好的办法是开始时将 1,000 到 5,000 个文档作为一个批次, 如果你的文档非常大,那么就减少批量的文档个数。
密切关注你的批量请求的物理大小往往非常有用,一千个 1KB 的文档是完全不同于一千个 1MB 文档所占的物理大小。 一个好的批量大小在开始处理后所占用的物理大小约为 5-15 MB。
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }} //删除
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}//添加
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }} //创建或者新增
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }//部分更新
{ "doc" : {"title" : "My updated blog post"} }
多索引,多类型
然而,经常的情况下,你想在一个或多个特殊的索引并且在一个或者多个特殊的类型中进行搜索。我们可以通过在URL中指定特殊的索引和类型达到这种效果,如下所示:
-
/_search
在所有的索引中搜索所有的类型
-
/gb/_search
在
gb
索引中搜索所有的类型 -
/gb,us/_search
在
gb
和us
索引中搜索所有的文档 -
/g\*,u\*/_search
在任何以
g
或者u
开头的索引中搜索所有的类型 -
/gb/user/_search
在
gb
索引中搜索user
类型 -
/gb,us/user,tweet/_search
在
gb
和us
索引中搜索user
和tweet
类型 -
/_all/user,tweet/_search
在所有的索引中搜索
user
和tweet
类型
分页搜索
SQL 使用 LIMIT
关键字返回单个 page
结果的方法相同,Elasticsearch 接受 from
和 size
参数:
-
size
显示应该返回的结果数量,默认是
10
-
from
显示应该跳过的初始结果数量,默认是
0
GET /_search?size=5 GET /_search?size=5&from=5 GET /_search?size=5&from=10
ElasticSerach 查询常用关键字
must
文档 必须 匹配这些条件才能被包含进来。
must_not
文档 必须不 匹配这些条件才能被包含进来。
should
如果满足这些语句中的任意语句,将增加 _score
,否则,无任何影响。它们主要用于修正每个文档的相关性得分。
filter
必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档
range
范围查询使用
gt
大于
gte
大于等于
lt
小于
lte
小于等于
term
term
查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed
的字符串
terms
terms
查询和 term
查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值
exits查询和missing查询
exists
查询和 missing
查询被用于查找那些指定字段中有值 (exists
) 或无值 (missing
) 的文档。这与SQL中的 IS_NULL
(missing
) 和 NOT IS_NULL
(exists
) 在本质上具有共性.
sort
对参数进行排序
springboot 整合 Elasticsearch
选择合适的springboot版本
Spring boot 2.2.8.RELEASE + ElasticSerach6.8+Spring Data Elasticsearch
POM文件
-
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.8.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <!--elasticsearch--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
application.yaml
spring:
application:
name: search
jackson:
default-property-inclusion: non_null
elasticsearch:
rest: #这里是针对Rest客户端
password: elastic
username: elastic
uris: http://127.0.0.1:9200
使用步骤
构建Entity
构建Entity,Entity对象与ES中的doc一一对应,@Data使用了lombok,indexName是索引名称,type是文档类型,Id指明文档唯一标识
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3RhdZmEv-1597631933357)(C:\Users\Waspal\Desktop\elastic\image-20200727155314727.png)]
继承ESRepository接口
继承ESRepository接口即可完成数据交互层的编写,UserRepository上不用加注解,其他SpringBean可以自由的@Autowire注入该类。该类中也可以加一些自己的方法,方法名字是有规范的,参考文档里的就行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F1Y28mVe-1597631933360)(C:\Users\Waspal\Desktop\elastic\image-20200727155330525.png)]
根据方法名解析对应的查询语句
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHxJbpsr-1597631933361)(C:\娱乐\微信\WeChat Files\wxid_ua1cewf9f1se22\FileStorage\File\2020-07\elastic\image-20200728172311702.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6pTtQSJR-1597631933363)(C:\娱乐\微信\WeChat Files\wxid_ua1cewf9f1se22\FileStorage\File\2020-07\elastic\image-20200728172326884.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fjGrcL7U-1597631933364)(C:\娱乐\微信\WeChat Files\wxid_ua1cewf9f1se22\FileStorage\File\2020-07\elastic\image-20200728172340114.png)]
@Query
使用@Query注解进行自定义查询
@Query中Value可以参考Elasticserach中查询的参数写法。