基于spring-boot-starter-data-elasticsearch整合elasticsearch于window系统

本文介绍了如何在SpringBoot项目中集成Elasticsearch,包括依赖管理、配置类的设置、YAML配置、创建索引库结构、Repository接口的使用,以及地理位置的自定义查询。
摘要由CSDN通过智能技术生成

使用环境:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

在配置环境中会需要到elasticsearch和kibana,这两个和spring-boot-starter-data-elasticsearch都必须得保持版本一致,我们可以通过查看他maven的配置:

比如我使用的是 spring-boot-starter-data-elasticsearch:2.7.3 查看到他的maven的结构后可以看到他们都指向了elasticsearch的一个版本7.17.4,因此在电脑上的配置好对应的版本

官方下载elasticsearch地址:Past Releases of Elastic Stack Software | Elastic

git下载elasticsearch地址:Releases · elastic/elasticsearch · GitHub

官方下载kibana地址:Past Releases of Elastic Stack Software | Elastic

git下载elasticsearch地址:Releases · elastic/kibana · GitHub

ik分词器下载地址:Releases · infinilabs/analysis-ik · GitHub

不用太在意我的7.16.2版本,只是当时不懂事的失败品(哭) 

创建配置类:

config:

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;

@Configuration
public class RestClientConfiguration extends AbstractElasticsearchConfiguration {

    @Value("${ES.host}")
    private String host;

    @Value("${ES.post}")
    private String post;

    @Override
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(host + ":" + post)
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

yml文件:

ES:
  host: localhost
  post: 9200

这样配置可以满足各种加入许多不同的需求,具体有什么我也不懂(哭),还有一个简单的配置直接在yml中配置,与上面不同的就是只能满足简单的需求

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: localhost:9200

 以下代码都是基于我做的例子来展示,如果有需要还是得看:

Spring Data Elasticsearch - 参考文档

创建索引库结构:

@Document(indexName = "posts")//索引库名称
public class Posts {
    @Id
    private Long id;

    @Field(type = FieldType.Text, 
            analyzer = "ik_max_word")
    //类型text,analyzer 则是使用ak分词器的 粗颗粒分词
    private String title;

    @Field(type = FieldType.Text,
            analyzer = "ik_max_word")
    private String content;

    @Field(type = FieldType.Date,
            format = DateFormat.custom,
            pattern = "yyyy-MM-dd HH:mm:ss")
    //类型为date,这里的format和pattern是为了规定出时间的格式便于程序与es数据传递
    private LocalDateTime createTime;

    @Field(type = FieldType.Date,
            format = DateFormat.custom,
            pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

    @Field(type = FieldType.Integer)//类型int
    private int likeCount;

    @Field(type = FieldType.Integer)
    private int commentCount;

    @Field(type = FieldType.Text)
    private String tags;

    @Field(type = FieldType.Text)
    private String imageUrls;

    @Field(type = FieldType.Integer)
    private int bookmarkedCount;

    @Field(type = FieldType.Integer)
    private int shareCount;

    @Field(type = FieldType.Integer)
    private int viewCount;

    @Field(type = FieldType.Integer)
    private int isDelete;

    @Field(type = FieldType.Keyword)//类型关键字
    private String type;

    private String latitude;//纬度

    private String longitude;//经度

    @GeoPointField//如果想使用地理查询就需要配置该注解,创建一个 GeoPoint 的对象
    private GeoPoint location;//els的地理位置

    @Field(type = FieldType.Double)
    private double sort;//els综合排序字段
}

创建出来在es查看的索引库结构为:

"posts" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "bookmarkedCount" : {
          "type" : "integer"
        },
        "commentCount" : {
          "type" : "integer"
        },
        "content" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        },
        "createTime" : {
          "type" : "date",
          "format" : "yyyy-MM-dd HH:mm:ss"
        },
        "id" : {
          "type" : "long"
        },
        "imageUrls" : {
          "type" : "text"
        },
        "isDelete" : {
          "type" : "integer"
        },
        "latitude" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "likeCount" : {
          "type" : "integer"
        },
        "location" : {
          "type" : "geo_point"
        },
        "longitude" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "shareCount" : {
          "type" : "integer"
        },
        "sort" : {
          "type" : "double"
        },
        "tags" : {
          "type" : "text"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        },
        "type" : {
          "type" : "keyword"
        },
        "updateTime" : {
          "type" : "date",
          "format" : "yyyy-MM-dd HH:mm:ss"
        },
        "viewCount" : {
          "type" : "integer"
        }
      }
    }

这里有一个很有意思的点是我对 

private String latitude;//纬度

private String longitude;//经度

这两个字段是什么都没有配置的,但是在索引库中却对它进行了一定的分析构建

"latitude" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },

"longitude" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }

这比我自己写的还好(哭) ,如果有想法可以尝试对一些没什么特殊需求的字段,进行不带任何注解进行创建索引库

Repository类:

public interface PostRepository extends ElasticsearchRepository<Posts, Long> {
}

这就是Repository类,要继承ElasticsearchRepository,两个范型分别为索引库的对应类,以及里面索引库主键的类型,它里面有着许多自定义方法,比如

可以起着与ES查询类似的方法名来进行简单的查询,这些在官方文档,又或者其它文章也有相关的解释(其实是我不会这个哭)

自定义查询:

@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;

@Resource
private PostRepository postRepository;

//Spring提供的一个查询条件构建器,帮助构建json格式的请求体
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

nativeSearchQueryBuilder
        .withQuery(QueryBuilders
            .boolQuery()//选择bool查询 这里也可以直接选择其他查询不要bool,只是当前例子需要去掉被删除的帖子
            .must(QueryBuilders.termQuery("isDelete", 1))//去掉被删除的帖子 两个参数为:1.需要进行判断的字段 2.该值为1时去掉
            .must(QueryBuilders.multiMatchQuery(postPageDTO.getKeyWord(), "title", "content")))//添加分词查询 两个参数:1.需要匹配的数据 2.在那个字段中需要进行匹配,这里我对title,content两个字段都用了ik分词器
        .withSorts(SortBuilders.scoreSort());//添加按词频排序

//构建查询信息
NativeSearchQuery searchQuery = nativeSearchQueryBuilder
                                    .withPageable(PageRequest.of(postPageDTO.getPageNum() - 1, postPageDTO.getPageSize()))//添加分页查询 由于ES页码由0开始需要减一
                                    .build();//构建

//用els查询
SearchHits<Posts> search = elasticsearchRestTemplate.search(searchQuery, Posts.class);

关于地理位置的自定义查询:

@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;

@Resource
private PostRepository postRepository;

//此处直接有代码截来。但是知道他代表什么就行
double latitude = postPageDTO.getLocationDTO().getLatitude();//纬度
double longitude = postPageDTO.getLocationDTO().getLongitude();//经度

// 间接实现QueryBuilder接口
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

// 以某点为中心,搜索指定范围
GeoDistanceQueryBuilder distanceQueryBuilder = new GeoDistanceQueryBuilder("location");//这个参数的是对应索引库字段的地理位置字段

distanceQueryBuilder.point(latitude, longitude)//创建以什么为中心的经纬度地址
        distance(postPageDTO.getDistance(), DistanceUnit.KILOMETERS);//两个参数:1.设定查找的距离 2.定位查询单位:公里

//封装查询
boolQueryBuilder.filter(distanceQueryBuilder);

nativeSearchQueryBuilder
        .withQuery(QueryBuilders//添加位置查询同时去除掉被删除的帖子 这一部分与上面雷同
            .boolQuery()
            .must(QueryBuilders.termQuery("isDelete", 1))
            .must(boolQueryBuilder))
         .withSorts(SortBuilders
            .geoDistanceSort("location", latitude, longitude) //三个参数;1.对应索引库字段的地理位置字段 2和3:创建以什么为中心的经纬度地址
            .unit(DistanceUnit.KILOMETERS)//定位查询单位:公里
            .order(SortOrder.ASC));// 按距离升序

//构建查询信息
NativeSearchQuery searchQuery = nativeSearchQueryBuilder
                                    .withPageable(PageRequest.of(postPageDTO.getPageNum() - 1, postPageDTO.getPageSize()))//添加分页查询 由于ES页码由0开始需要减一
                                    .build();//构建

//用els查询
SearchHits<Posts> search = elasticsearchRestTemplate.search(searchQuery, Posts.class);
  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值