Elasticsearch基本使用

一、Kibana:可视化界面

1、创建一个名为tets_lsl的索引,设置索引的分片数为3,备份数为2。

PUT test_lsl
或
PUT test_lsl
{
    "settings" : {
        "index" : {
            "number_of_shards" : 3,
            "number_of_replicas" : 2
        }
    }
}
或
PUT test_lsl
{
    "settings" : {
        "number_of_shards" : 3,
        "number_of_replicas" : 2
    }
}

说明:
默认的分片数是5到1024
默认的备份数是1
索引的名称必须是小写的,不可重名

2、添加映射

 PUT /test_lsl/_mapping
 {
   "properties":{
     "name":{
       "type":"text"
     },
     "age":{
       "type":"integer"
     },
     "addr":{
       "type":"keyword"
     }
   }
 }

3、添加数据

指定id
POST /test_lsl/_doc/1
不指定id
POST /test_lsl/_doc
{
  "name":"小王",
  "age":18,
  "addr":"秦国"
}

4、查询数据

#查询所有
GET /test_lsl/_search
GET /test_lsl/_search
{
  "query": {
    "match_all": {}
  }
}
#根据条件查询
{
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
          	#如果age是text类型,查询字段替换为为"age.keyword"
            "age": [
              "187",
              "13"
            ],
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "_source": {
  	#查询字段
    "includes": [
    ],
 	 #排除字段
    "excludes": []
  }
}
#

5、删除数据

#删除指定id数据
DELETE  /test_lsl/_doc/1
# 清空满足条件数据
POST person1/_delete_by_query
{  
  "query": {
    "match_all": {}
  }
}

6、跟新数据

跟新数据要添加所有数据(类似于先删除数据,再添加数据)

1、先查询对应数据
GET  /test_lsl/_search
{
  "query": {
    "match": {
      "recordId": "210391039470214144"
    }
  }
}

2、通过id更新文档
PUT /test_lsl/_doc/对应索引id
{
  "name":"小王",
  "age":18,
  "addr":"秦国"
}

7、分词器:ik_max_word(更细致)和ik_smart模式。

二、Elasticsearch在java中的使用

1、导入依赖

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

2、创建配置类

@Configuration
public class ElasticSearchConfig {

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

    @Value("${elasticsearch.port}")
    private Integer esPort;
    
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(
            RestClient.builder(new HttpHost(esHost, esPort, null)));
    }
}

3、多条件查询BoolQueryBuilder

BoolQueryBuilder queryBuilder= QueryBuilders.boolQuery();
1.matchAllQuery匹配所有
queryBuilder.matchAllQuery();
//字段存在
QueryBuilders.existsQuery("organization")

2.termQuery精准匹配,大小写敏感且不支持
queryBuilder.termQuery("key", value) 一次匹配一个值,完全匹配
queryBuilder.termsQuery("key", obj1, obj2..)   一次匹配多个值
queryBuilder.termsQuery("key", List<T> list)   一次匹配多个值

3.matchPhraseQuery对中文精确匹配
queryBuilder.matchPhraseQuery("key", value)

4.matchQuery("key", Obj) 单个匹配
queryBuilder.matchQuery(key, value);

5.multiMatchQuery("text", "field1", "field2"..); 
queryBuilder.multiMatchQuery(value, key1, key2, key3);

6.组合查询
  注:must:and、mustNot:not 、should:or
 queryBuilder.must(QueryBuilders.termQuery("name", "小王"))
            .mustNot(QueryBuilders.termQuery("age", 18))
            .should(QueryBuilders.termQuery("addr", "秦国"));

4、构建查询条件(仅供参考)

#查询参数如果为text类型,后面拼接keyword,如:"username"-->"username.keyword"

    /**
     * 构建单值查询条件
     *
     * @param indices       索引
     * @param paramName     参数名称
     * @param value         查询字段
     * @param queryFields   查询返回字段
     * @param excludeFields 排除字段
     */
    public static SearchRequest matchSearchRequest(String indices, String paramName, Object value,
        String[] queryFields,
        String[] excludeFields) {
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder(paramName, value);
        sourceBuilder.query(matchQueryBuilder);
        sourceBuilder.fetchSource(queryFields, excludeFields);
        searchRequest.source(sourceBuilder);
        return searchRequest;
    }

	 /**
     * 构建多值查询条件
     *
     * @param indices       索引
     * @param paramName     参数名称
     * @param value         查询字段集合
     * @param queryFields   查询返回字段
     * @param excludeFields 排除字段
     */
    public static SearchRequest searchRequest(String indices, String paramName, List<?> value,
        String[] queryFields,
        String[] excludeFields) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.termsQuery(paramName, value));
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.fetchSource(queryFields, excludeFields);
        SearchRequest searchRequest = new SearchRequest(indices);
        searchRequest.source(sourceBuilder);
        return searchRequest;

    /**
     * 字段数组包含参数查询
     *
     * @param indices       索引
     * @param paramName     参数名称(存储值为数组)
     * @param value         查询字段
     * @param queryFields   查询返回字段
     * @param excludeFields 排除字段
     */
    public static SearchRequest searchRequestInArray(String indices, String paramName, Object value,
        String[] queryFields,
        String[] excludeFields) {
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termsQuery(paramName, value));
        sourceBuilder.fetchSource(queryFields, excludeFields);
        searchRequest.source(sourceBuilder);
        return searchRequest;
    }
    }

    /**
     * 计算字段数组包含参数的值的和
     *
     * @param indices        索引
     * @param paramName      参数名称(存储值为数组)
     * @param value          查询字段
     * @param resultName     统计结果字段名
     * @param calculateField 被计算字段
     */
    public static SearchRequest sumSearchRequestInArray(String indices, String paramName, Object value,
        String resultName, String calculateField) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termsQuery(paramName, value));
        sourceBuilder.fetchSource(false);
        sourceBuilder.aggregation(AggregationBuilders.sum(resultName).field(calculateField));
        SearchRequest searchRequest = new SearchRequest(indices);
        searchRequest.source(sourceBuilder);
        return searchRequest;
    }

4.1构建多条件查询

		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        BoolQueryBuilder boolQueryBuilder1 = QueryBuilders.boolQuery();
        boolQueryBuilder1.must(
            QueryBuilders.multiMatchQuery(key, value).type(MultiMatchQueryBuilder.Type.PHRASE)
        );
        BoolQueryBuilder boolQueryBuilder2 = QueryBuilders.boolQuery();
        boolQueryBuilder2.should(
            QueryBuilders.multiMatchQuery(key, value).type(MultiMatchQueryBuilder.Type.PHRASE)
        );
        BoolQueryBuilder boolQueryBuilder3 = QueryBuilders.boolQuery();
        boolQueryBuilder2.mustNot(
            QueryBuilders.multiMatchQuery(key, value).type(MultiMatchQueryBuilder.Type.PHRASE)
        );
        boolQuery.must(boolQueryBuilder1);
        boolQuery.must(boolQueryBuilder2);
        boolQuery.must(boolQueryBuilder3);

4.2取消分词器

条件构造后面添加:type(MultiMatchQueryBuilder.Type.PHRASE)
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must().type(MultiMatchQueryBuilder.Type.PHRASE));

5、封装查询结果

    /**
     * 封装返回参数到实体类
     *
     * @param search    elasticsearch查询结果
     * @param classType 返回类型
     * @param <T>       返回类型
     * @return T
     */
    public static <T> List<T> convertSearchResponseToEntity(SearchResponse search, Class<T> classType) {
        List<T> results = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            Map<String, Object> map = hit.getSourceAsMap();
            T result = JSON
                .parseObject(JSON.toJSONString(map), classType);
            results.add(result);
        }
        return results;
    }

    /**
     * 封装基本类型返回参数
     *
     * @param search    elasticsearch查询结果
     * @param classType 返回类型
     * @param <T>       返回类型
     * @return T
     */
    public static <T> List<T> convertSearchResponse(SearchResponse search, Class<T> classType) {
        List<T> results = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            Collection<Object> values = hit.getSourceAsMap().values();
            for (Object value : values) {
                T result = JSON
                    .parseObject(JSON.toJSONString(value), classType);
                results.add(result);
            }
        }
        return results;
    }

6、更新数据

    public void testUpdateEs(String indices) {
        UpdateByQueryRequest updateByQuery = new UpdateByQueryRequest("my_index");
        //设置分片并行
        updateByQuery.setSlices(2);
        //设置版本冲突时继续执行
        updateByQuery.setConflicts("proceed");
        //设置更新完成后刷新索引 ps很重要如果不加可能数据不会实时刷新
        updateByQuery.setRefresh(true);
        //查询条件如果是and关系使用must 如何是or关系使用should
        List<String> list = List.of("10", "20");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
            .must(new MultiMatchQueryBuilder("age", "title", "username").type(MultiMatchQueryBuilder.Type.PHRASE));
        updateByQuery.setQuery(boolQueryBuilder);
        //设置要修改的内容可以多个值多个用;隔开
        1.替换 =
        updateByQuery.setScript(new Script("ctx._source['eventId'] =6L"));
        2.追加 +=
        updateByQuery.setScript(new Script("ctx._source['eventId'] +=6L"));
		3.字段为数组
		updateByQuery.setScript(new Script("ctx._source['age'].add(15L)"));
		4.字段为数组并加上判定if
        updateByQuery.setScript(
            new Script(
                "if(ctx._source['age'] == null) {ctx._source['age']=[];ctx._source['age'].add(15L)} else{ctx._source['age'].add(15L)} "));
        try {
            BulkByScrollResponse response = client.
                updateByQuery(updateByQuery, RequestOptions.DEFAULT);
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

注:批量更新数据避免多次动态编译脚本,从而避免超过编译次数限制。
使用索引脚本或者带参数的脚本来替代您目前的内联脚本,这样可以减少脚本动态编译的次数
updateByQuery.setScript(new Script(ScriptType.INLINE, "painless", "ctx._source['recordId'] = params.recordId", Collections.singletonMap("recordId", id)));

7、查询处理es所有数据百万级

//引入依赖
	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>

//构造查询参数
public static void  matchSearchRequest(
        String[] queryFields,
        String[] excludeFields,String indices) throws Exception {
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //设置每次查询数量
        sourceBuilder.size(1000);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
            .must(QueryBuilders.matchAllQuery());
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.fetchSource(queryFields, excludeFields);
        searchRequest.source(sourceBuilder);
        searchAllByScroll(searchRequest);
    }

    /**
     * 针对查询请求,通过 Scroll 查询所有,不分页
     * @param request 查询请求
     * @return
     */
    public static void searchAllByScroll(SearchRequest request) throws Exception {

        RestHighLevelClient client = new RestHighLevelClient(
            RestClient.builder(new HttpHost("192.168.210.110", 29200, null))
                .setHttpClientConfigCallback(requestConfig ->
                    requestConfig.setKeepAliveStrategy((response, context) -> TimeUnit.MINUTES.toMillis(3)))
                .setRequestConfigCallback(
                    requestConfigBuilder -> requestConfigBuilder
                        .setConnectTimeout(3000)
                        .setSocketTimeout(120 * 1000)));

        request.scroll(TimeValue.timeValueSeconds(10));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        String scrollId = response.getScrollId();
        SearchHit[] searchHits = response.getHits().getHits();

        while (searchHits != null && searchHits.length > 0) {
            for (SearchHit hit : searchHits) {
           		 //具体操作数据
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            	MQProducer.send("192.168.210.51:39876", "resend_ic_tjsj-sz-info", sourceAsMap);
            }
            response = client.scroll(new SearchScrollRequest(scrollId).scroll(TimeValue.timeValueSeconds(10)), RequestOptions.DEFAULT);
            scrollId = response.getScrollId();
            searchHits = response.getHits().getHits();
        }
        
		//清除滚动,否则影响下次查询
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);
        ClearScrollResponse clearScrollResponse = null;
        try {
            clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest,RequestOptions.DEFAULT);
        } catch (IOException e) {
            System.out.println("滚动查询删除失败");
        }
        //清除滚动是否成功
        boolean succeeded = clearScrollResponse.isSucceeded();
        }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值