ES JAVA API Client 使用方法

        Java Api Client 属于7.15后的新特性,用起来感觉比原来HighLevelRestClient要简化很多,而且更接近dsl语句。

        我这里是某个特殊场景要用,资料不太多,只能自己摸索出的一点JAVA API Client使用方法,用作启发,作一些常用的操作应该没啥问题。

1、依赖

<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>7.17.6</version>
</dependency>

2、配置

这样配置,灵活一点

@ConfigurationProperties(prefix = "spring.elasticsearch.rest")
@Configuration
public class EsClientConfig {

    /**
     * 多个IP逗号隔开
     */
    @Setter
    private String uris;

    /**
     * 同步方式
     *
     * @return
     */
    @Bean
    public ElasticsearchClient elasticsearchClient() {
        HttpHost[] httpHosts = toHttpHost();

        // Create the RestClient
        RestClient restClient = RestClient.builder(httpHosts).build();

        // Create the transport with a Jackson mapper
        RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

        // create the API client
        return new ElasticsearchClient(transport);
    }

    @Bean
    public RestClient restClient() {
        HttpHost[] httpHosts = toHttpHost();

        // Create the RestClient

        return RestClient.builder(httpHosts).build();
    }

    /**
     * 解析配置的字符串hosts,转为HttpHost对象数组
     *
     * @return
     */
    private HttpHost[] toHttpHost() {
        if (!StringUtils.hasLength(uris)) {
            throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.rest.uris不能为空!");
        }

        // 多个IP逗号隔开
        String[] hostArray = uris.split(",");
        HttpHost[] httpHosts = new HttpHost[hostArray.length];
        HttpHost httpHost;
        for (int i = 0; i < hostArray.length; i++) {
            String[] strings = hostArray[i].split(":");
            httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
            httpHosts[i] = httpHost;
        }

        return httpHosts;
    }
}

3、使用

我这里例子有runtime_mappings、有script,没那么通用,用作类比还是比较合适:

意思是查询出idaas_log-*索引中被修改过(_version>1)的记录。

原dsl语句

GET /_search?version=true
{
  "runtime_mappings": {
    "trusted": {
      "type": "keyword",
      "script": {
        "source": "if (doc['_version'].value < 2 ) emit('0'); if (doc['_version'].value >= 2) emit('1');"
      }
    }
  },
  "fields": [
    "trusted"
  ],
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "_index": [
              "idaas_log-*"
            ]
          }
        },
        {
          "term": {
            "trusted": "1"
          }
        }
      ]
    }
  },
  "size": 10000
}

java实现

可以看到有很多java lambda 表达式写法

private final RestClient client;
private final ElasticsearchClient restClient;

private static final String TRUSTED = "trusted";
private static final String TRUSTED_VALUE = "1";
private static final String MATCH_INDEX = "_index";
private static final String FALSIFIED_SCRIPT = "if (doc['_version'].value < 2 ) emit('0'); if (doc['_version'].value >= 2) emit('1');";


//主要是这个方法,查询和上面dsl是完全一致的,看起来结构上是不是很类似
@Override
public List<FalsifiedData> queryFalsifiedDataList(List<String> indexList) throws BizException, IOException {
    List<FieldValue> fieldValues = new ArrayList<>();
    for (String s : indexList) {
        fieldValues.add(FieldValue.of(s));
    }
    SearchRequest request = SearchRequest.of(s -> s
            .runtimeMappings(TRUSTED, RuntimeField.of(f -> f
                    .type(RuntimeFieldType.Keyword)
                    .script(sc -> sc.inline(i -> i
                            .source(FALSIFIED_SCRIPT)))
            ))
            .fields(fi -> fi.field(TRUSTED))
            .query(q -> q
                  .bool(b -> b
                       .filter(f -> f
                              .terms(ts -> ts
                                    .field(MATCH_INDEX)
                                    .terms(tv -> tv.value(fieldValues))))
                       .filter(f -> f.term(t -> t.field(TRUSTED).value(TRUSTED_VALUE)))))
            .size(10000));
    SearchResponse<Map> response = restClient.search(request, Map.class);

    //将查询结果解析并提取索引名,唯一id,数据内容
    List<Hit<Map>> hits = response.hits().hits();
    List<FalsifiedData> falsifiedDataList = new ArrayList<>();
    for (Hit<Map> hit : hits) {
        FalsifiedData falsifiedData = new FalsifiedData();
        falsifiedData.setId(hit.id());
        falsifiedData.setIndexName(hit.index());
        if (Objects.nonNull(hit.source())) {
            falsifiedData.setContent(hit.source().toString());
        }
        falsifiedDataList.add(falsifiedData);
    }
    tagFalsifiedData(falsifiedDataList);
    return falsifiedDataList;
}

/**
 * 同步给被修改的数据打上标记
 *
 * @param falsifiedDataList 已篡改日志记录
 * @throws BizException 自定义异常
 * @throws IOException  IO异常
 */
public void tagFalsifiedData(List<FalsifiedData> falsifiedDataList) throws BizException {
    if (CollectionUtils.isNotEmpty(falsifiedDataList)) {
        for (FalsifiedData falsifiedData : falsifiedDataList) {
            Map<String, Object> doc = new HashMap<>(4);
            doc.put("integrity", "已篡改");
            try {
                restClient.update(builder -> builder
                        .index(falsifiedData.getIndexName())
                        .id(falsifiedData.getId()).doc(doc), Map.class);
            } catch (Exception e) {
                throw new BizException("elasticsearch更新数据(标记数据已篡改)异常");
            }
        }
    }
}
}

普通curl命令的执行

如查询索引的几个基本属性

GET /_cat/indices/gw_audit-*?v&s=index&h=index,uuid,docs.count,docs.deleted

java实现

​​​​​​​

 @Override
    public List<IndexDocCountDto> queryDeletedData(List<String> indexList) throws BizException, IOException {
        String str = indexList.get(0);
        for (int i = 1; i < indexList.size(); i++) {
            str = str.concat(",").concat(indexList.get(i));
        }
        Request request = new Request("GET", "/_cat/indices/".concat(str)
                .concat("?s=index&h=index,uuid,docs.count,docs.deleted"));
        Response response = null;
        try {
            response = client.performRequest(request);
        } catch (Exception e) {
            throw new BizException("elasticsearch日志查询异常");
        }
        HttpEntity entity = response.getEntity();
        String resultString = EntityUtils.toString(entity);

        //将查询得到的内容逐行解析,每行三个字段分别对应index、docCount、deletedCount
        String[] lineStrings = resultString.split("\n");
        List<IndexDocCountDto> docCountDtos = new ArrayList<>();
        for (String s : lineStrings) {
            String[] rowStrings = s.split("\\s+");
            String index = rowStrings[0];
            String esId = rowStrings[1];
            String count = rowStrings[2];
            String deletedCount = rowStrings[3];
            IndexDocCountDto docCountDto = new IndexDocCountDto(
                    index, esId, Long.parseLong(count) + Long.parseLong(deletedCount), Long.valueOf(deletedCount));
            docCountDtos.add(docCountDto);
        }
        return docCountDtos;
    }

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿星_Alex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值