一、环境二、集成步骤
2.1、引入依赖2.2、配置2.3、实体类2.3、基本操作
2.3.1、批量导入2.3.2、分页搜索并高亮2.3.3、常用DSL 三、项目分享
一、环境SpringBoot 2.3.0.RELEASEElasticsearch 7.13.4 二、集成步骤 2.1、引入依赖
SpringBoot中集成Elasticsearch,要注意一些依赖的版本和Elasticsearch服务器版本一致。
2.2、配置7.13.4 org.springframework.boot spring-boot-starter-data-elasticsearch org.elasticsearch.client elasticsearch-rest-high-level-client org.elasticsearch.client elasticsearch-rest-client org.elasticsearch elasticsearch org.elasticsearch.client elasticsearch-rest-high-level-client ${elasticsearch.version} org.elasticsearch.client elasticsearch-rest-client ${elasticsearch.version} org.elasticsearch elasticsearch ${elasticsearch.version}
application配置文件:
#elasticsearch spring.elasticsearch.rest.uris=124.223.44.254:9200 spring.elasticsearch.rest.username=elasticUser spring.elasticsearch.rest.password='Password123.'2.3、实体类
程序启动会默认据此实体类自动创建对应索引,
@Data
@document(indexName = PrescriptionPo.indexName)
public class PrescriptionPo implements Serializable {
private static final long serialVersionUID = 4138692353689910309L;
public static final String indexName = "prescription";
@Id
@JSONField(ordinal = 1)
private String id;
@Field(type = FieldType.Keyword)
@JSONField(ordinal = 2)
private String code;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
@JSONField(ordinal = 3)
private String detailContent;
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@JSONField(ordinal = 4)
private Date publishTime;
@Field(type = FieldType.Keyword)
@JSONField(ordinal = 5)
private String authorId;
@Field(index = true, type = FieldType.Text, analyzer = "ik_smart", store = false, searchAnalyzer = "ik_smart")
@JSONField(ordinal = 6)
private String authorName;
@JSONField(ordinal = 7)
private List picUrls;
@Field(type = FieldType.Keyword)
@JSONField(ordinal = 8)
private String requestUrl;
@Field(type = FieldType.Long)
@JSONField(ordinal = 9)
private Long batchId;
}
若因某些ES服务版本导致不能生成正确的索引映射,也可通过DSL提前手动创建索引,
PUT prescription
{
"mappings" : {
"properties" : {
"authorId" : {
"type" : "keyword"
},
"authorName" : {
"type" : "text",
"analyzer" : "ik_smart"
},
"batchId" : {
"type" : "long"
},
"code" : {
"type" : "keyword"
},
"detailContent" : {
"type" : "text",
"analyzer" : "ik_max_word"
},
"id" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"picUrls" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"publishTime" : {
"type" : "date",
"format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"requestUrl" : {
"type" : "keyword"
}
}
}
}
2.3、基本操作
SpringBoot里操作Elasticsearch有很多种方式,可以使用SpringData的ElasticsearchRepository实现简单的操作,可以使用SpringData的ElasticsearchRestTemplate实现更复杂的操作如搜索高亮和批量导入等操作,也可以自己封装一个通过操作DSL的Restful客户端,更加自由。
2.3.1、批量导入public void sync(List2.3.2、分页搜索并高亮prescriptionPoList) { List queries = new ArrayList<>(); IndexCoordinates indexCoordinates = IndexCoordinates.of(PrescriptionPo.indexName); int count = 0; for (PrescriptionPo po : prescriptionPoList) { IndexQuery query = new IndexQuery(); query.setId(po.getId()); query.setSource(JSON.toJSONString(po)); queries.add(query); // 每批次1000条提交索引 if (count != 0 && count % 1000 == 0) { elasticsearchRestTemplate.bulkIndex(queries, indexCoordinates); queries.clear(); } count++; } // 不足一批次的最后提交 if (queries.size() > 0) { elasticsearchRestTemplate.bulkIndex(queries, indexCoordinates); } elasticsearchRestTemplate.indexOps(indexCoordinates).refresh(); log.info("Finished bulk {}!", prescriptionList.size()); }
使用ElasticsearchRestTemplate配合SearchHits实现分页搜索并高亮显示,
@Override public PagesearchPrescription(String keyword, Integer pageNum, Integer pageSize) { Pageable pageable = PageRequest.of(pageNum - 1, pageSize); NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder(); HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field(new HighlightBuilder.Field("detailContent")); highlightBuilder.preTags("").postTags(""); searchQueryBuilder.withPageable(pageable) .withQuery(QueryBuilders.matchQuery("detailContent", keyword)) .withHighlightBuilder(highlightBuilder); SearchHits searchHits = elasticsearchRestTemplate.search(searchQueryBuilder.build(), PrescriptionPo.class); // 创建list对象 List prescriptionDtoList = new ArrayList<>(); searchHits.forEach(item -> { PrescriptionPo prescriptionPo = item.getContent(); prescriptionDtoList.add(prescriptionPo.makeDto(item)); }); // 组装分页对象 Page page = new PageImpl<>(prescriptionDtoList, pageable, searchHits.getTotalHits()); return page; }
使用ElasticsearchRepository则不能同时实现分页搜索和高亮,
public interface PrescriptionRepository extends ElasticsearchRepository2.3.3、常用DSL{ // 用DSL,对detailContent分词后搜索 @Query("{"match": {"detailContent": "?0"}}") @Highlight( fields = {@HighlightField(name = "detailContent")}, parameters = @HighlightParameters(preTags = {""}, postTags = {""}, numberOfFragments = 0) ) List > matchByContentWithDsl(String detailContent, Pageable pageable); // 支持分页,不支持高亮 @Query("{"match": {"detailContent": "?0"}}") Page matchByContentWithDsl2(String detailContent, Pageable pageable); Optional findByCode(String code); }
GET _cat/indices?v
GET _cat/plugins
GET _search
{
"query": {
"match_all": {}
}
}
GET /_analyze
{
"text":"中华人民共和国国徽",
"analyzer":"ik_smart"
}
DELETe prescription
GET prescription/_mappings
GET prescription/_count
GET prescription/_search?pretty&from=0&size=2
GET prescription/_search?pretty&from=0&size=2
{
"query": {
"match": {
"detailContent": "咳嗽"
}
},
"highlight" : {
"pre_tags" : [""],
"post_tags" : [""],
"fields" : {
"detailContent" : {}
}
}
}
GET prescription/_search?pretty
{
"query": {
"wildcard": {
"code": "*LaONPnzhG"
}
},
"sort": [
{
"publishTime": {
"order": "desc"
}
}
]
}
GET prescription/_search?pretty&from=0
{
"query": {
"bool": {
"must": [
{
"term": {
"code": "Lbzt9cKrB"
}
}
]
}
}
}
GET prescription/_search?q=*&sort=publishTime:desc&pretty
# 指定字段更新
POST prescription/_update/1642665269755_RTX4FX
{
"doc": {
"detailContent": "xx"
}
}
# 全字段更新
POST prescription/_doc/9gUwDn0BA5KB_D7SWQLN
{
"detailContent": "xxx"
}
# 分组统计每批各自总数
GET prescription/_search?pretty
{
"size": 0,
"aggs": {
"group_by_batchId": {
"terms": {
"field": "batchId"
}
}
}
}
# 并计算每批的平均发布时间,因为请求setsize=0,所以响应仅包含聚合结果
GET prescription/_search?pretty
{
"size": 0,
"aggs": {
"group_by_batchId": {
"terms": {
"field": "batchId"
},
"aggs": {
"average_publishTime": {
"avg": {
"field": "publishTime"
}
}
}
}
}
}
# 备份到新索引
POST _reindex
{
"source": {
"index": "prescription"
},
"dest": {
"index": "prescription_copy20220110"
}
}
三、项目分享
分享一个搜索头疼脑热和中药信息的网址,
https://124.223.54.92/ 或 http://124.223.54.92/,
Ps,其中所有信息仅供娱乐!
Ps,其中所有信息仅供娱乐!
Ps,其中所有信息仅供娱乐!
因使用了自己生成的ssl证书,可能谷歌浏览器打不开网址,提示您的连接不是私密连接,
在浏览器页面键入thisisunsafe即可。



