草庐IT

java Api操作Elasticsearch

$驽马十驾$ 2023-08-10 原文

Java Api操作Elasticsearch

本次使用 elasticsearch 版本为7.17.0,建议使用 7.X 版本,8.1.2版本会遇到一些 Springboot(本人使用版本2.6.6) 版本不兼容的问题。此文章会列举一个例子。

导包

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

创建客户端

我们在测试类中先创建一个客户端,用来向 ES 发送请求

	//创建ES客户端
	RestHighLevelClient esClient = new RestHighLevelClient(
    	RestClient.builder(new HttpHost("localhost", 9200, "http"))
	);

索引操作

创建索引

测试代码如下:

	//创建索引
	CreateIndexRequest request = new CreateIndexRequest("user");
	CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT);
	//响应状态
	boolean acknowledged = response.isAcknowledged();
	System.out.println("索引操作:" + acknowledged);

	//关闭ES客户端
	esClient.close();

控制台输出信息如下:

此处会遇到坑:
运行之后报错信息如下:

Exception in thread "main" ElasticsearchStatusException[Elasticsearch exception [type=illegal_argument_exception, reason=request [/book] contains unrecognized parameter: [include_type_name]]]

原因是:CreateIndexRequest 对象有两个,导报如果是下面这个包就会报错,因为已经不推荐使用此对象去创建索引,可以看到 create() 方法也有不推荐的横线

import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;

应该导包如下:

import org.elasticsearch.client.indices.CreateIndexRequest;

查看索引

测试代码如下:

	//查询索引
	GetIndexRequest getIndexRequest = new GetIndexRequest("user");
	GetIndexResponse getIndexResponse = esClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
	//相应状态
	System.out.println(getIndexResponse.getSettings());

	//关闭ES客户端
	esClient.close();

控制台输出信息如下:

{user={"index.creation_date":"1650436113234","index.number_of_replicas":"1","index.number_of_shards":"1","index.provided_name":"user","index.routing.allocation.include._tier_preference":"data_content","index.uuid":"XhZ5LlZxSJaVG3Zmjs4YJQ","index.version.created":"8010299"}}

删除索引

测试代码如下:

 	//删除索引
	DeleteIndexRequest user = new DeleteIndexRequest("user");
	AcknowledgedResponse delete = esClient.indices().delete(user, RequestOptions.DEFAULT);
	//相应状态
	System.out.println("delete:" + delete.isAcknowledged());

	//关闭ES客户端
	esClient.close();

控制台输出信息如下:

文档操作

新增文档

测试代码如下:

		//创建请求对象(指明索引和ID)
        IndexRequest request = new IndexRequest();
        request.index("user").id("1001");

        User user = new User();
        user.setName("wangda");
        user.setAge(30);
        user.setSex("男");

        ObjectMapper mapper = new ObjectMapper();
        String userJson = mapper.writeValueAsString(user);
        request.source(userJson, XContentType.JSON);

        IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
        System.out.println(response.getResult());

        //关闭ES客户端
        esClient.close();

此时遇到 ES8.1.2 版本与 Springboot 不兼容的问题:
报错信息如下:

ElasticsearchException[java.util.concurrent.ExecutionException: java.net.ConnectException: Timeout connecting to [/10.253.117.204:9200]

但是通过 ApiPost 查看数据已插入

经测试,ES 7.17.0 版本正常!

批量新增文档

测试代码如下:

//创建批量新增请求对象
	BulkRequest request = new BulkRequest();
	request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "猪八戒", "age", 20, "sex", "男"));
	request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "沙悟净", "age", 18, "sex", "男"));
	request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "白龙马", "age", 16, "sex", "女"));
	//客户端发送请求
	BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
	//打印结果信息
	System.out.println("took:" + response.getTook());
	System.out.println("items:" + response.getItems());

	//关闭ES客户端
	esClient.close();

控制台输出信息如下:

根据ID查询文档

测试代码如下:

	GetRequest request = new GetRequest();
	request.index("user").id("1001");
	GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
	System.out.println(response.getSourceAsString());

//关闭ES客户端
esClient.close();

控制台输出结果如下:

查询所有文档

测试代码如下:

//创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有数据
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        request.source(sourceBuilder);
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        //关闭ES客户端
        esClient.close();

控制台响应结果如下:

根据ID删除文档

测试代码如下:

		//创建删除请求对象
        DeleteRequest request = new DeleteRequest();
        request.index("user").id("1001");

        DeleteResponse delete = esClient.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.getResult());

        //关闭ES客户端
        esClient.close();

控制台响应结果如下:

批量删除文档

测试代码如下:

		//创建批量删除请求对象
        BulkRequest request = new BulkRequest();
        request.add(new DeleteRequest().index("user").id("1002"));
        request.add(new DeleteRequest().index("user").id("1003"));
        request.add(new DeleteRequest().index("user").id("1004"));
        //客户端发送请求
        BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
        //打印结果信息
        System.out.println("took:" + response.getTook());
        System.out.println("items:" + response.getItems());

        //关闭ES客户端
        esClient.close();

控制台响应结果如下:

修改文档

测试代码如下:

		//创建修改请求对象
        UpdateRequest request = new UpdateRequest();
        request.index("user").id("101");
        request.doc(XContentType.JSON, "name", "孙悟空");

        UpdateResponse update = esClient.update(request, RequestOptions.DEFAULT);
        System.out.println(update.getResult());

        //关闭ES客户端
        esClient.close();

控制台响应结果如下:

高级查询

条件查询

测试代码如下:

		//创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询请求体
        request.source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("age", 30)));
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        //查询匹配
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出结果如下:

分页查询

测试代码如下:

		//创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询的请求体
        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).from(0).size(2));

        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

排序

测试代码如下:

		//创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询请求体
        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort("age", SortOrder.DESC));

        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

{
  "_index" : "user",
  "_type" : "_doc",
  "_id" : "1001",
  "_score" : null,
  "_source" : {
    "name" : "孙悟空",
    "age" : 30,
    "sex" : "男"
  },
  "sort" : [
    30
  ]
}
{
  "_index" : "user",
  "_type" : "_doc",
  "_id" : "1002",
  "_score" : null,
  "_source" : {
    "name" : "猪八戒",
    "age" : 20,
    "sex" : "男"
  },
  "sort" : [
    20
  ]
}
{
  "_index" : "user",
  "_type" : "_doc",
  "_id" : "1003",
  "_score" : null,
  "_source" : {
    "name" : "沙悟净",
    "age" : 18,
    "sex" : "男"
  },
  "sort" : [
    18
  ]
}
{
  "_index" : "user",
  "_type" : "_doc",
  "_id" : "1004",
  "_score" : null,
  "_source" : {
    "name" : "白龙马",
    "age" : 16,
    "sex" : "女"
  },
  "sort" : [
    16
  ]
}

过滤字段(返回指定字段)

测试代码如下:

		//创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询请求体
        //过滤字段
        String[] excludes = {"age"};//排除字段
        String[] includes = {};//包含字段
        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).fetchSource(includes, excludes));

        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

范围查询

测试代码如下:

		//创建请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询请求体
        //大于等于
        //小于等于
        request.source(new SearchSourceBuilder().query(new RangeQueryBuilder("age").gte("20").lte("30")));

        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

模糊查询(相似的意思)

测试代码如下:

//创建请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建请求体(这里的name故意写错一个字母wangdb,真实数据是wangda)
        request.source(new SearchSourceBuilder().query(QueryBuilders.fuzzyQuery("name", "wangdb").fuzziness(Fuzziness.ONE)));

        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }
    }

控制台输出信息如下:

模糊查询(类似于MySQl的like)

测试代码如下:

		//创建请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建请求体(*类似于MySQL中的%,是通配符,表示零个或多个字符,?表示一个字符)
        request.source(new SearchSourceBuilder().query(QueryBuilders.wildcardQuery("name", "*悟*")));

        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

高亮查询

测试代码如下:

		//创建请求对象
        SearchRequest request = new SearchRequest().indices("user");
        //构建请求体
        //创建查询请求体构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //构建查询方式:高亮查询
        MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("name", "孙悟空");

        //构建高亮字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>");//设置标签前缀
        highlightBuilder.postTags("</font>");//设置标签后缀
        highlightBuilder.field("name");//设置高亮字段
        //设置高亮构建对象
        sourceBuilder.highlighter(highlightBuilder);
        //设置查询方式
        sourceBuilder.query(matchPhraseQueryBuilder);
        //设置请求体
        request.source(sourceBuilder);


        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

bool查询

测试代码如下:

		//创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("user");
        //构建查询请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //必须包含(30岁的男性)
        boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
        boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "男"));
        //必须不
//        boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name","孙"));
        //可能包含
//        boolQueryBuilder.should(QueryBuilders.matchQuery("name","白"));

        sourceBuilder.query(boolQueryBuilder);
        request.source(sourceBuilder);
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit);
        }

控制台输出信息如下:

bool查询可以组合各种复杂的条件查询,比如类似于MySQL中的:where 条件1 and (条件2 or 条件3)

有关java Api操作Elasticsearch的更多相关文章

  1. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  2. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  3. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  4. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

  5. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  6. ruby - Rails Elasticsearch 聚合 - 2

    不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a

  7. elasticsearch源码关于TransportSearchAction【阶段三】 - 2

    1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>

  8. Postman测试简单操作 - 2

    1、接口请求基本操作1.1例子tips在view的选项可以zoomin调整窗口字帖大小。1、创建一个测试的workspace,并命名为test2、test后面新增一个addrequest3、选择发送GET,URL为一个开源的https://api.apiopen.top/api/sentences获取每日一句4、点击send查看内容Tips:如果提示出现Error:tunnelingsocketcouldnotbeestablished,statusCode=407错误,参照以下解决办法)关于tunnelingsocketcouldnotbeestablished,cause=getaddri

  9. 【Linux操作系统】——网络配置与SSH远程 - 2

    Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好

  10. ruby - Ruby 语言可以用来构建操作系统吗? - 2

    Ruby语言是否可以用于创建全新的移动操作系统或桌面操作系统,即是否可以用于系统编程? 最佳答案 嗯,现在有一些操作系统使用比C更高级的语言。基本上,ruby解释器本身需要用一些低级的东西来编写,并且需要一些引导加载代码将功能齐全的ruby​​解释器作为独立内核加载到内存中。一旦ruby​​解释器被引导并以内核模式(或innerrings之一)运行,就没有什么可以阻止您在其上构建整个操作系统。不幸的是,它可能会很慢。每个操作系统功能的垃圾收集可能会相当引人注目。ruby解释器将负责任务调度和网络堆栈等基本事情,使用垃圾收集框架会大大

随机推荐