Java操作ElasticSearch7.10.0

用以致学,最近搞数据地图项目,元数据存储到ElasticSearch(ES)中快速检索,需要用java操作ES,研究研究写个DEMO,备忘,有需要的同学也可以看看。

代码都放这了:https://github.com/clj198606061111/spring-boot2-elasticsearch-demo

分三种方式操作ES

  • spring-data-elasticsearch
  • elasticsearch-rest-client
  • elasticsearch-rest-high-level-client

spring-data-elasticsearch

核心依赖

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
    <version>4.1.1</version>
</dependency>

springdata 操作ES的CRUD代码

public interface BookRepository extends ElasticsearchRepository<Book, String> {

    /*
    在Spring Data reppository支持直接按名字解析,但是起的方法名要按照一定的规则来取,解析的时候会
    剥离以下的套词,然后对剩下的部分进行解析,查询的套词如下:find…By, read…By, query…By, count…By和get…By,
    反正不管怎样,By后面就是实际查询条件的开始,一般都是基于实体的属性作条件,条件之间使用And或者Or来连接,比如
    findBookByIdAndName, findBookByNameOrAuth
     */
    Book findByName(String name);

    List<Book> findByAuthor(String author);

    Book findBookById(String id);
}

@Service
public class BookServiceImpl implements BookService {

    @Resource
    private BookRepository bookRepository;

    public Book add(Book book) {
        return bookRepository.save(book);
    }

    public Book update(Book book) {
        Book bookR = bookRepository.findBookById(book.getId());
        if (null == bookR) {
            return book;
        }
        bookR.setAuthor(book.getAuthor());
        bookR.setName(book.getName());
        return bookRepository.save(bookR);
    }

    public boolean delById(String id) {
        bookRepository.deleteById(id);
        return true;
    }

    public Book getById(String id) {
        return bookRepository.findBookById(id);
    }

    public Iterable<Book> findAll() {
        Pageable pageable = PageRequest.of(1, 10);
        return bookRepository.findAll(pageable);
    }

    @Override
    public Page<Book> queryPage(Integer pageNum, Integer pageSize, Book book) {

        //分页是从第0页开始的
        Pageable pageable = PageRequest.of(pageNum, pageSize);

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        if (!ObjectUtils.isEmpty(book.getName())) {
            builder.withQuery(QueryBuilders.matchQuery("name", book.getName()));
        }
        if (!ObjectUtils.isEmpty(book.getDesc())) {
            builder.withQuery(QueryBuilders.matchQuery("desc", book.getDesc()));
        }
        builder.withPageable(pageable);
        return bookRepository.search(builder.build());
    }
}

elasticsearch-rest-client

核心依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.10.0</version>
</dependency>

java 低级rest客户端操作ES的CRUD代码

@Service
public class EsServiceImpl implements EsService {

    private Logger logger = LoggerFactory.getLogger(EsServiceImpl.class);

    @Resource
    private RestClient client;

    @Override
    public Book edit(Book book) throws IOException {
        // 构造HTTP请求,第一个参数是请求方法,第二个参数是服务器的端点,host默认是http://localhost:9200,
        // endpoint直接指定为index/type的形式
        Request request = new Request(HttpMethod.POST.name(), new StringBuilder("/book/_doc/").
                append(book.getId()).toString());
        // 设置其他一些参数比如美化json
        request.addParameter("pretty", "true");

        // 设置请求体并指定ContentType,如果不指定默认为TEXT_PLAIN,
        //设置ContentType.APPLICATION_JSON,UTF-8格式,中文不会乱码
        request.setEntity(new NStringEntity(JSON.toJSONString(book), ContentType.APPLICATION_JSON));

        // 发送HTTP请求
        Response response = client.performRequest(request);

        // 获取响应体, id: AWXvzZYWXWr3RnGSLyhH
        String responseBody = EntityUtils.toString(response.getEntity());
        logger.info(responseBody);
        return book;
    }

    @Override
    public boolean delById(String id) throws IOException {
        Request request = new Request(HttpMethod.DELETE.name(),
                new StringBuilder("/book/_doc/").append(id).toString());
        Response response = client.performRequest(request);
        String responseBody = EntityUtils.toString(response.getEntity());
        logger.info(responseBody);
        return true;
    }

    @Override
    public Book getById(String id) throws IOException {
        Request request = new Request(HttpMethod.GET.name(),
                new StringBuilder("/book/_doc/").append(id).toString());
        Response response = client.performRequest(request);
        String responseBody = EntityUtils.toString(response.getEntity());
        logger.info(responseBody);
        return EsUtil.pass(responseBody, Book.class);
    }

    @Override
    public boolean update(String id, Book book) throws IOException {
        // 构造HTTP请求
        Request request = new Request("POST", new StringBuilder("/book/_doc/").
                append(id).append("/_update").toString());

        // 将数据丢进去,这里一定要外包一层“doc”,否则内部不能识别
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("doc", book);
        request.setEntity(new NStringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON));

        // 执行HTTP请求
        Response response = client.performRequest(request);

        // 获取返回的内容
        String responseBody = EntityUtils.toString(response.getEntity());
        logger.info(responseBody);
        return true;
    }

    @Override
    public boolean updateDescByScript(String id, String desc) throws IOException {
        // 构造HTTP请求
        Request request = new Request("POST", new StringBuilder("/book/_doc/").
                append(id).append("/_update").toString());

        JSONObject jsonObject = new JSONObject();
        // 创建脚本语言,如果是字符变量,必须加单引号
        StringBuilder op1 = new StringBuilder("ctx._source.desc=").append("'" + desc + "'");
        jsonObject.put("script", op1);

        request.setEntity(new NStringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON));

        // 执行HTTP请求
        Response response = client.performRequest(request);

        // 获取返回的内容
        String responseBody = EntityUtils.toString(response.getEntity());
        logger.info(responseBody);
        return true;
    }

    @Override
    public List<Book> queryByName(String name) throws IOException {
        Request request = new Request("POST", new StringBuilder("/book/_doc/_search").toString());

        JSONObject query = new JSONObject();
        JSONObject match = new JSONObject();
        JSONObject termName = new JSONObject();
        termName.put("name", name);
        match.put("match", termName);
        query.put("query", match);

        logger.info(JSON.toJSONString(query));

        request.setEntity(new NStringEntity(JSON.toJSONString(query), ContentType.APPLICATION_JSON));

        // 执行HTTP请求
        Response response = client.performRequest(request);

        // 获取返回的内容
        String responseBody = EntityUtils.toString(response.getEntity());
        logger.info(responseBody);

        return null;
    }
}

elasticsearch-rest-high-level-client

核心依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.10.0</version>
</dependency>

java 高级客户端操作ES的CRUD代码,个人感觉封装得有点复杂,还是需要非常熟悉ES的rest 低级接口才能容易理解并用高级客户端实现逻辑CRUD。

@Service
public class EsServiceImpl implements EsService {

    @Resource
    private RestHighLevelClient client;

    private static final String INDEX_CITY = "city";

    private static final String TYPE = "_doc";

    @Override
    public City add(City city) throws IOException {
        client.index(new IndexRequest(INDEX_CITY).id(String.valueOf(city.getId())).source(JSON.toJSONString(city), XContentType.JSON), RequestOptions.DEFAULT);
        return city;
    }

    @Override
    public City update(City city) throws IOException {
        client.update(new UpdateRequest(INDEX_CITY, String.valueOf(city.getId())).doc(new IndexRequest(INDEX_CITY).id(String.valueOf(city.getId())).source(JSON.toJSONString(city), XContentType.JSON)), RequestOptions.DEFAULT);
        return city;
    }

    @Override
    public boolean delById(Integer id) throws IOException {
        client.delete(new DeleteRequest(INDEX_CITY).id(String.valueOf(id)), RequestOptions.DEFAULT);
        return true;
    }

    @Override
    public City getById(Integer id) throws IOException {
        GetResponse response = client.get(new GetRequest(INDEX_CITY, String.valueOf(id)), RequestOptions.DEFAULT);
        return JSON.parseObject(response.getSourceAsString(), City.class);
    }

    @Override
    public List<City> queryByName(String name) throws IOException {
        SearchRequest request = new SearchRequest();
        request.scroll(new TimeValue(1, TimeUnit.HOURS)); //滚动游标保留多久
        request.setBatchedReduceSize(10);//每批次拉多少条
        request.indices(INDEX_CITY);

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.prefixQuery("name", name));
        PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("name", name);
        sourceBuilder.query(prefixQueryBuilder);
        sourceBuilder.timeout(TimeValue.timeValueMinutes(2L));
        //sourceBuilder.size(10);//分页量
        //sourceBuilder.sort("name", SortOrder.DESC);//排序

        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        return Arrays.asList(response.getHits().getHits()).stream().map(obj -> JSON.parseObject(obj.getSourceAsString(), City.class)).collect(Collectors.toList());
    }
}
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值