Spring BOOT 整合 Elastic Search 6.5及基本使用

Spring BOOT 整合 Elastic Search 6.5及基本使用

  • 下载
  • maven引入jar
  • 整合配置类
  • highLevel使用实例
    • 1.单个新增
    • 2.单个修改
    • 3.删除
    • 4.批量操作
    • 5.查询(重要)
      • 5.1 简单匹配
      • 5.2 聚合查询
        • 5.2.1 按日期复合聚合
        • 5.2.2 按某个值多类型聚合
        • 5.2.3 按某个值具体条件聚合
        • 5.2.4 按需求返回多个聚合结果
      • 5.3 nested内部集合查询

记录不易,转载分享请注明出处!

声明:学习于https://www.kaifaxueyuan.com/server/elasticsearch7.html官网,官网是7.X,此贴用的6.5
(elastic官网也有中文教程和代码实例,但基于2.X让人望而却步。。。由于最近项目需要整合ES,根据网上教程以及自己的摸索有了一定的成果,故此开贴)

下载

官网:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
可视化和语句工具按需求引入,官网推荐kibana
我自己用的elastic-search-head

maven引入jar

		<!--es restClient-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>6.5.0</version>
        </dependency>
        <!-- Java High Level REST Client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.5.0</version>
        </dependency>
        <!--es 核心包-->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.5.0</version>
        </dependency>
        <!--es嗅探器-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client-sniffer</artifactId>
            <version>6.5.0</version>
        </dependency>

整合配置类

application.yml:

elasticsearch:
    hostname: 192.168.X.1XX
    port: 9200
@Configuration
public class RestClientConfig {
     

    @Value("${elasticsearch.hostname}")
    private String hostname;

    @Value("${elasticsearch.port}")
    private int port;
    
 	@Bean
    public RestHighLevelClient restHighLevelClient() {
     
        //如果有多个从节点可以持续在内部new多个HttpHost,
        //参数1是IP,参数2是端口,参数3是通信协议
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(hostname, port, "http"))
        );
    }

highLevel使用实例

1.单个新增

	@Autowired
    private RestHighLevelClient highLevelClient;

	public JSONObject add() throws IOException {
     
		//统一的返回类型
        JSONObject response = newJSON(0, "success");
        // IndexRequest
        // 自定义构造的实体
        String id = KeyUtil.getTimeAndRandomString();
        Entity entity = new Entity(id);

		//用的net.sf.json
        String source = JSONObject.fromObject(entity).toString();
        // index
        IndexRequest indexRequest = new IndexRequest("index");
        indexRequest.id(id);
        // type
        indexRequest.type("report");
        //立即刷新
        indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        //语句
        indexRequest.source(source, XContentType.JSON);
        // 操作ES
        IndexResponse indexResponse = highLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        response.setDomain(indexResponse);
        return response;
    }

2.单个修改

public JSONObject update(Entity entity) throws IOException {
     
        JSONObject response = newJSON(0, "success");
        String source = JSONObject.fromObject(entity).toString();

        // updateRequest
        // 参数1:index 2:type 3:id
        UpdateRequest updateRequest = new UpdateRequest("index", "type", entity.getId());
        //语句
        updateRequest.doc(source, XContentType.JSON);
        //立即刷新
        updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        // 操作ES
        UpdateResponse updateResponse = highLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        response.setDomain(updateResponse);
        return response;
    }

3.删除

public JSONObject deleteBy() throws IOException {
     
        JSONObject response = newJSON(0, "success");
        // 根据ID单个删除
        //参数1:index 2:type 3:id
        DeleteRequest deleteRequest = new DeleteRequest("index", "type", "id");
        deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        highLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        //deleteByQuery
        DeleteByQueryRequest request = new DeleteByQueryRequest("index");
        request.setDocTypes("type");
        // key1,key2都是es中的字段
        MatchPhraseQueryBuilder phrase1 = QueryBuilders.matchPhraseQuery("key1", 2);
        MatchPhraseQueryBuilder phrase2 = QueryBuilders.matchPhraseQuery("key2", 1200);
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(phrase1)
                .must(phrase2);
        request.setQuery(queryBuilder);
        request.setRefresh(true);
        BulkByScrollResponse resp = highLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
        response.setDomain(resp);
        return response;
    }

4.批量操作

 public JSONObject batch(List<Entity> entities) throws IOException {
     
        JSONObject response = newJSON(0, "success");
        // BulkRequest
        BulkRequest bulkRequest = new BulkRequest();

        for (Entity entity: entities) {
     
            String id = KeyUtil.getTimeAndRandomString();
            String source = JSONObject.fromObject(entity).toString();
            // IndexRequest
            IndexRequest indexRequest = new IndexRequest("index")
                    .id(id).type("type").source(source, XContentType.JSON);
            
            bulkRequest.add(indexRequest);
        }
        //修改
        UpdateRequest updateRequest = new UpdateRequest("index", "index", "id");
        bulkRequest.add(updateRequest);
        //删除
        DeleteRequest deleteRequest = new DeleteRequest("index", "index", "id");
        bulkRequest.add(deleteRequest);

		//立即刷新
        bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        // 操作ES
        BulkResponse bulkResponse = highLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        response.setDomain(bulkResponse);
        return response;
    }

5.查询(重要)

5.1 简单匹配

public JSONObject queryBy(EntityQueryVo vo) throws IOException {
     
	JSONObject response = newJSON(0, "success");
	//页数
	int current = (int) vo.getCurrent();
	//每页数量
	int size = (int) vo.getSize();
	int from = (current - 1) * size;

	SearchRequest searchRequest = new SearchRequest("index","index2").types("type","type2");
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
	//match和term的区别是,match查询的时候,elasticsearch会根据你给定的字段提供合适的分析器,而term查询不会有分析器分析的过程
    //match查询相当于模糊匹配,只包含其中一部分关键词就行
	MatchQueryBuilder match = QueryBuilders.matchQuery("content", "可信");
    //term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇
	TermQueryBuilder term = QueryBuilders.termQuery("content", "这是原文");
    //模糊查询- prefix前缀
    PrefixQueryBuilder prefix = QueryBuilders.prefixQuery("content", "这");
    //模糊查询- wildcard通配
    WildcardQueryBuilder wildcard = QueryBuilders.wildcardQuery("content", "*文*");
	//指定查询 phrase
    MatchPhraseQueryBuilder phrase = QueryBuilders.matchPhraseQuery("entity_id", "20200422160127278XiV4FlYYdUKnpafImi1FEWQ");
    //范围 range
    RangeQueryBuilder range = QueryBuilders.rangeQuery("recv_date").gte("2020-04-21 16:01:27").lte("2020-04-24 16:01:31");
    //完全匹配多个值
    List<Float> floats = new ArrayList<>();
    floats.add(66.41f);
    floats.add(34.84f);
    floats.add(110.2f);
    TermsQueryBuilder terms = QueryBuilders.termsQuery("frequency", floats);
    
    //按需求加入
    queryBuilder.must(match)
    .must(term)
    .must(terms);
    
     searchSourceBuilder.query(queryBuilder);
     searchSourceBuilder.size(size);
     searchSourceBuilder.from(from);
     searchRequest.source(searchSourceBuilder);
     SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
     //命中的记录
     SearchHit[] searchHits = searchResponse.getHits().getHits();
     //命中的总数(不受分页限制)
     int total = (int) searchResponse.getHits().totalHits;
}

5.2 聚合查询

5.2.1 按日期复合聚合

public JSONObject queryBy(EntityQueryVo vo) throws IOException {
     
        JSONObject response = newJSON(0, "success");

        SearchRequest searchRequest = new SearchRequest("index", "index2").types("type", "type2");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //queryBuilder里边可以设置外部条件,如时间,具体匹配值等
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        //date_key: 自定义聚合字段
        DateHistogramAggregationBuilder dateAggBuilder = AggregationBuilders.dateHistogram("date_key");
        //field_key: es中字段
        //dateHistogramInterval是日期聚合类型,有分,时,日,周,月,年,也可以指定到具体几分钟聚合查询
        dateAggBuilder.field("field_key").dateHistogramInterval(DateHistogramInterval.HOUR);

        //可按需求加入子条件;举例:查询每小时中,entity_type的各个值的字段
        TermsAggregationBuilder typeGroup = AggregationBuilders.terms("type_agg").field("entity_type");
        dateAggBuilder.subAggregation(typeGroup);

        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.aggregation(dateAggBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        Aggregation aggregation = searchResponse.getAggregations().get("date_key");
        List<? extends Histogram.Bucket> buckets = ((Histogram) aggregation).getBuckets();
        for (Histogram.Bucket bucket : buckets) {
     
            //具体处理
            //bucket中是每个小时内的聚合结果,以及按entity_type的各个值聚合的子结果
        }
    }

5.2.2 按某个值多类型聚合

TermsAggregationBuilder typeGroup = AggregationBuilders.terms("type_agg").field("entity_type");
searchSourceBuilder.aggregation(typeGroup);

5.2.3 按某个值具体条件聚合

AggregationBuilder keyGroup = AggregationBuilders.filter("type1", QueryBuilders.matchPhraseQuery("entity_type", 1));
searchSourceBuilder.aggregation(keyGroup);

5.2.4 按需求返回多个聚合结果

AggregationBuilder group1 = AggregationBuilders....
AggregationBuilder group2 = AggregationBuilders....
AggregationBuilder group3 = AggregationBuilders....
searchSourceBuilder.aggregation(group1);
searchSourceBuilder.aggregation(group2);
searchSourceBuilder.aggregation(group3);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

5.3 nested内部集合查询

es中大部分都会遇到这样的数据结构:

{
     
	"id": "2001",
	"templateName": "name",
	"templateRemark": "beizhu",
	"details": [{
     
		"key":"1021",
		"value":"nested值"
		},
		{
     
		"key":"1021",
		"value":"nested值"
		}
	]
}
		

要求:
向es中建表时,以上的数据格式,details的type需要为"type": “nested”,不然匹配就会异常命中

public JSONObject queryBy(EntityQueryVo vo) throws IOException {
     
        JSONObject response = newJSON(0, "success");

        SearchRequest searchRequest = new SearchRequest("index", "index2").types("type", "type2");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //queryBuilder里边可以设置外部条件,如时间,具体匹配值等
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        
        BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
        TermQueryBuilder term = QueryBuilders.termQuery("details.key", "key");
        nestedBoolQuery.must(term);
        NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("details", nestedBoolQuery, ScoreMode.None);

	 	queryBuilder.must(nestedQueryBuilder);
        searchSourceBuilder.query(queryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
}

先总结到这里,后边遇到了更多的ES操作再进行补充,有不对的地方也希望各位看客大佬们指正!

你可能感兴趣的:(ES,elasticsearch,java)