使用环境:

org.springframework.boot

spring-boot-starter-data-elasticsearch

在配置环境中会需要到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 {

}

这就是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 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 search = elasticsearchRestTemplate.search(searchQuery, Posts.class);

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: