springboot集成elasticsearch

2年前 (2022) 程序员胖胖胖虎阿
278 0 0

Springboot集成elasticsearch

Springboot集成elasticsearch有多种方式,如TransportClient、
RestHighLevelClient等等;但是官方已经停止更新TransportClient并且在elasticsearch8.0之后已经弃用,所以本人使用的是RestHighLevelClient。

引入pom文件

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

增加配置

配置文件

elasticsearch:
  url: 127.0.0.1
  port: 9200

配置类

@Configuration
public class ElasticSearchConfig {
    
    @Value("#{elasticsearch.url}")
    private String url;

    @Value("#{elasticsearch.port}")
    private String port;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost(url, 9200)));
        return client;
    }
}

工具类

创建索引

public Boolean createIndex(String indexNam) {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexNam.toLowerCase());
        createIndexRequest.settings(Settings.builder().put("index.number_of_shards", 4)
            .put("index.number_of_replicas", 2));
        try {
            XContentBuilder xContentBuilder= XContentFactory.jsonBuilder();
            xContentBuilder.startObject().startObject("properties")
                    .startObject("type").field("type", "integer").endObject()
                    .startObject("content").field("type", "text").field("analyzer", "ik_max_word").endObject()
                    .endObject().endObject();
            createIndexRequest.mapping(xContentBuilder);
            CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            boolean acknowledged = response.isAcknowledged();
            // 指示是否在超时之前为索引中的每个分片启动了必需的分片副本数
            boolean shardsAcknowledged = response.isShardsAcknowledged();
            if (acknowledged || shardsAcknowledged) {
                log.info("创建索引成功!索引名称为{}", indexNam);
                return Boolean.TRUE;
            }
        } catch (IOException e) {
            log.info("创建索引失败{}",e);
        }
        return Boolean.FALSE;
    }

创建索引CreateIndexRequest这里只传索引名称,没有类型了,因为elasticsearch7.6 索引将去除type 没有类型的概念了。
elasticsearch有自己的数据类型如下

核⼼数据类型

一、字符串类型
1)text:用于全文索引,搜索时自动使用分词器分词后匹配
2)keyword:不分词,精确匹配
二、数字类型
1)整数类型:integer、long、byte、short
2)浮点类型: float,、half_float、 scaled_float、double
三、日期类型:date
但是如果我们传入的json字符串怎么办?
#插入|更新此字段的值时,有3种表示方式
#使用固定格式的字符串
“2020-04-18”、“2020/04/18 09:00:00”
#值使用长整型的时间戳,1970-01-01 00:00:00,s
1610350870
#值使用长整型的时间戳,ms
1641886870000
四、布尔 boolean

分词类型

analyzer:ik_max_word 表示会对文本做最细 力度的拆分
analyzer:ik_smart 表示会对文本做最粗粒度的拆分

删除/是否存在索引

public Boolean isIndexExists(final String indexName) {
    try {
        GetIndexRequest request = new GetIndexRequest(indexName.toLowerCase());
        return restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
    } catch (IOException e) {
        log.info("查看索引是否存在失败{}",e);
        return Boolean.FALSE;
    }
}

public Boolean removeIndex(String indexName) {
    try {
        DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest(indexName.toLowerCase());
        AcknowledgedResponse acknowledgedResponse=restHighLevelClient.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);
        if(acknowledgedResponse.isAcknowledged()){
            return Boolean.TRUE;
        }
    } catch (IOException e) {
       log.error("删除索引失败{}",e);
    }
    return Boolean.FALSE;
}

保存Docment数据

    public Boolean saveDocment(ElasticSearchCommon elasticSearchCommon) {
        if(!this.isIndexExists(elasticSearchCommon.getIndexName().toLowerCase())){
            this.createIndex(elasticSearchCommon);
        }
        IndexRequest indexRequest=new IndexRequest(elasticSearchCommon.getIndexName());
        indexRequest.id(elasticSearchCommon.getId());
        indexRequest.timeout("3s");
        indexRequest.source(JSON.toJSONString(elasticSearchCommon), XContentType.JSON);
        IndexResponse response = null;
        try {
            response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.info("存储文档失败{}",e);
        }
        return response.getShardInfo().getSuccessful()>0?true:false;
    }

es存储文档的时候不需要创建索引index,可以自动创建index,但是字段类型都是默认的,所以重要的字段一定要自己创建。

删除文档

    public Boolean delDocment(String id, String indexName) {
        DeleteRequest deleteRequest=new DeleteRequest();
        deleteRequest.timeout("3s");
        deleteRequest.id(id);
        DeleteResponse deleteResponse = null;
        try {
            deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.info("删除文档失败{}",e);
        }
        return deleteResponse.getShardInfo().getSuccessful()>0?true:false;
    }

搜索

    public PageResult<ElasticSearchResponseBean> searchIndex(final ElasticSearchRequestBean elasticSearchRequestBean) {
        SearchRequest searchRequest = new SearchRequest(elasticSearchRequestBean.getIndexName());
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from((elasticSearchRequestBean.getPage().getPageNum()-1)*elasticSearchRequestBean.getPage().getPageSize());
        searchSourceBuilder.size(elasticSearchRequestBean.getPage().getPageSize());
        searchSourceBuilder.trackTotalHits(true);//用于显示正确的总数
        BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
        if(StringUtils.isNotEmpty(elasticSearchRequestBean.getKeyWord())){
            FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("content", elasticSearchRequestBean.getKeyWord());
            boolQueryBuilder.must(fuzzyQueryBuilder);
        }
        if(elasticSearchRequestBean.getType()!=null){
            TermQueryBuilder termQueryBuilder=QueryBuilders.termQuery("type",elasticSearchRequestBean.getType());
            boolQueryBuilder.must(termQueryBuilder);
        }
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(3, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        PageResult<ElasticSearchResponseBean> pageResult=new PageResult<>();
        List<ElasticSearchResponseBean> list=new ArrayList<>();
        Long total=0L;
        try {
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            if (search.getHits().getHits().length!=0){
                Map<Object,Object> map=null;
                for (SearchHit documentFields : search.getHits().getHits()) {
                    map=new HashMap<>();
                    map.putAll(documentFields.getSourceAsMap());
                    list.add(BeanUtil.mapToObj(map,ElasticSearchResponseBean.class));
                }
                total=search.getHits().getTotalHits().value;
            }
            pageResult.setRecord(list);
            pageResult.setTotalCount(total);
            pageResult.setCurrentPage(elasticSearchRequestBean.getPage().getPageNum());
            pageResult.setPageSize(elasticSearchRequestBean.getPage().getPageSize());
            pageResult.setPageCount(total/elasticSearchRequestBean.getPage().getPageSize());
            return pageResult;
        } catch (IOException e) {
            log.info("搜索失败{}",e);
        }
        return pageResult;
    }

elasticsearch搜索条件比较多,简单是说几个
BoolQueryBuilder:多条件查询器
TermQueryBuilder:单条件查询器
FuzzyQueryBuilder :模糊查询器
所有的查询器都要通过searchSourceBuilder进行查询;
想要什么的查询器可以去QueryBuilders类中查看;
如果项目中搜索不是基于算分进行排序的,可以搜索的时候取消算分功能加快查询效率
1、自定义排序规则不会算分
2、无评分查询器,ConstantScoreQueryBuilder

MatchQueryBuilder matchQueryBuilder= QueryBuilders.matchQuery("content", keyWord);
            ConstantScoreQueryBuilder constantScoreQueryBuilder=QueryBuilders.constantScoreQuery(matchQueryBuilder);
            searchSourceBuilder.query(constantScoreQueryBuilder);

版权声明:程序员胖胖胖虎阿 发表于 2022年10月2日 下午1:48。
转载请注明:springboot集成elasticsearch | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...