【ElasticSearch】(三、常见方法总结)
前言:演示版本为7.6.1
一、SpringBoot整合ElasticSearch
1. 添加文件ElasticSearchConfig
package com.tm.es.config; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ElasticSearchConfig { @Bean public RestHighLevelClient restHighLevelClient (){ RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost",9200,"http"))); return client; } }
2. 添加配置文件application.yml
server: port: 8080 spring: application: name: spring-boot-es-demo elasticsearch: rest: #username: user #password: 123456 uris: https://127.0.0.1:9200 # http连接超时时间 connection-timeout: 1000 # socket连接超时时间 socketTimeout: 30000 # 获取连接的超时时间 connectionRequestTimeout: 500 # 最大连接数 maxConnTotal: 100 # 最大路由连接数 maxConnPerRoute: 100 # 任务最长可执行时间 (单位:小时) executeTimeout: 8
3. 添加相关依赖pom.xml
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch --> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.6.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.6.1</version> </dependency>
4. controller中注入RestHighLevelClient
至此,一个简易的环境就搭好了,可以方便我们进行下面demo的练习了。
5. 创建实体类User用于业务开发
@Data @AllArgsConstructor @NoArgsConstructor @ToString public class User { private String name; private String full_name; private Integer age; @JSONField(format="yyyy-MM-dd HH:mm:ss") private LocalDateTime birthday; private Date createTime; private Long timestamp; private Boolean isBoy; }
二、常用的方法总结
通过浏览器访问:http://localhost:8080/ES/existIndex即可完成调试
package com.tm.es.controller; import com.alibaba.fastjson.JSON; import com.tm.es.entity.User; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.Cancellable; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.*; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.*; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.elasticsearch.search.sort.SortOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; /** * @version 1.0 * @ClassName EsTest * @Description * @Author tianmeng * @Date 2020/12/16 10:26 */ @Slf4j @RestController @RequestMapping("/ES") public class EsController { @Autowired private RestHighLevelClient client; //-------------------------------------------------查看索引是否存在------------------------------------------------ @RequestMapping("/existIndex") public boolean existIndex() throws IOException { GetIndexRequest request = new GetIndexRequest("test_index"); boolean exists = client.indices().exists(request, RequestOptions.DEFAULT); return exists; } //----------------------------------------------------查看索引信息---------------------------------------------------- @RequestMapping("/getIndex") public void getIndex() throws IOException { GetIndexRequest request = new GetIndexRequest("test_index"); GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT); //获取索引信息 Map<String, List<AliasMetaData>> aliases = response.getAliases(); Map<String, MappingMetaData> mappings = response.getMappings(); Map<String, Settings> settings = response.getSettings(); } //----------------------------------------------------查看所有索引信息---------------------------------------------------- @RequestMapping("/getAllIndex") public void getAllIndex() throws IOException { //查看所有索引信息 //GetIndexRequest request = new GetIndexRequest("*"); //查看符合条件的索引信息 GetIndexRequest request = new GetIndexRequest("test_*"); GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT); String[] indices = response.getIndices(); } //----------------------------------------------------创建索引---------------------------------------------------- //1.创建索引(同步) @RequestMapping("/createIndex1") public void createIndex1() throws IOException { //如果存在该索引会报错 //使用默认的settings CreateIndexRequest request = new CreateIndexRequest("test_index"); CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT); System.out.println(response); } //2.创建索引(同步) @RequestMapping("/createIndex2") public void createIndex2() throws IOException { CreateIndexRequest request = new CreateIndexRequest("test_index"); // settings部分的设置 request.settings(Settings.builder() // 创建索引时,分配的主分片的数量 .put("index.number_of_shards", 2) // 创建索引时,为每一个主分片分配的副本分片的数量 .put("index.number_of_replicas", 2) ); CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT); } //3.创建索引(异步) @RequestMapping("/createIndex3") public void createIndex3(){ CreateIndexRequest request = new CreateIndexRequest("test_index"); client.indices().createAsync(request, RequestOptions.DEFAULT, new ActionListener<CreateIndexResponse>() { @Override public void onResponse(CreateIndexResponse createIndexResponse) { log.debug("执行情况:" + createIndexResponse); System.out.println(createIndexResponse); } @Override public void onFailure(Exception e) { log.error("执行失败的原因:" + e.getMessage()) ; System.out.println(e.getMessage()); } }); } //----------------------------------------------------删除索引---------------------------------------------------- @RequestMapping("/deleteIndex") public boolean deleteIndex() throws IOException { //没有该索引会报错 DeleteIndexRequest request = new DeleteIndexRequest("test_index"); AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT); return delete.isAcknowledged(); } //----------------------------------------------------更新索引settings---------------------------------------------------- @RequestMapping("/updateIndexSettings") public void updateIndexSettings() throws IOException { UpdateSettingsRequest request = new UpdateSettingsRequest("test_index"); Settings.Builder settingsBuilder = Settings.builder().put("index.number_of_replicas", "3"); request.settings(settingsBuilder); // 是否更新已经存在的settings配置 默认false (false的时候可以更新成功 true的时候不成功) //request.setPreserveExisting(false); // 更新settings配置(同步) AcknowledgedResponse acknowledgedResponse = client.indices().putSettings(request, RequestOptions.DEFAULT); System.out.println(acknowledgedResponse.isAcknowledged()); } //----------------------------------------------------更新索引mapping---------------------------------------------------- @RequestMapping("/updateIndexMapping") public void updateIndexMapping() throws IOException { //这里要注意:已经创建好的文档字段不能删除和更改类型以及里面的属性,但是可以添加字段, //如果想要修改,需要新创建一个索引,之后将原索引中的数据同步过去,指定别名,最后删除原索引 PutMappingRequest request = new PutMappingRequest("test_index"); XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); { builder.startObject("properties"); { //String text 分词 builder.startObject("name"); { builder.field("type","text"); builder.field("analyzer", "ik_max_word"); } builder.endObject(); //String keyword 不分词 builder.startObject("full_name"); { builder.field("type","keyword"); } builder.endObject(); //Numeric integer builder.startObject("age"); { builder.field("type","integer"); } builder.endObject(); //Date date builder.startObject("birthday"); { builder.field("type","date"); builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"); } builder.endObject(); //Data date builder.startObject("createTime"); { builder.field("type","date"); builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"); } builder.endObject(); //Numeric long builder.startObject("timestamp"); { builder.field("type","long"); } builder.endObject(); //Boolean boolean builder.startObject("isBoy"); { builder.field("type","boolean"); } builder.endObject(); } builder.endObject(); } builder.endObject(); request.source(builder); // 新增mapping配置(同步) AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT); System.out.println(response); } //----------------------------------------------------添加文档(单个 同步+异步)---------------------------------------------------- @RequestMapping("/addDocument") public void addDocument() throws IOException { User user = new User(); user.setName("张三"); user.setFull_name("张三李四王五赵六"); user.setAge(12); user.setIsBoy(true); user.setTimestamp(System.currentTimeMillis());//存入的是毫秒值1608108501654 user.setCreateTime(new Date());//存入的是毫秒值1608108501654 user.setBirthday(LocalDateTime.now());////存入的是时间格式2020-12-16 16:48:21 IndexRequest request = new IndexRequest("test_index"); // 规则 put /test_index/_doc/1 //不指定id会随机生成 有该id会更新 没有该id会添加 //request.id("1"); request.timeout(TimeValue.timeValueSeconds(1)); request.source(JSON.toJSONString(user), XContentType.JSON); //同步 IndexResponse response = client.index(request, RequestOptions.DEFAULT); // 结果:IndexResponse[index=test_index,type=_doc,id=nGvFanYBf998z9yKoZFx,version=1,result=created,seqNo=3,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}] System.out.println(response.toString()); //新建:CREATED 更新:OK System.out.println(response.status()); //异步 // Cancellable cancellable = client.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() { // @Override // public void onResponse(IndexResponse indexResponse) { // //这里可以获取添加的数据 // log.debug("执行情况: " + indexResponse); // } // // @Override // public void onFailure(Exception e) { // log.error("执行失败的原因"); // } // }); } //----------------------------------------------------添加文档(单个 map方式)---------------------------------------------------- @RequestMapping("/addDocumentByMap") public void addDocumentByMap() throws IOException { Map<String, Object> map = new HashMap<>(); map.put("name", "张三"); map.put("full_name", "测试测试"); map.put("age", 45); map.put("birthday", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now())); map.put("createTime", System.currentTimeMillis()); map.put("timestamp", System.currentTimeMillis()); map.put("isBoy", false); IndexRequest request = new IndexRequest("test_index"); request.id("kk"); request.source(map); IndexResponse response = client.index(request, RequestOptions.DEFAULT); System.out.println(response.status()); } //----------------------------------------------------添加文档(批量)---------------------------------------------------- @RequestMapping("/addBulkDocument") public void addBulkDocument() throws Exception { BulkRequest request = new BulkRequest(); request.timeout("15s"); List<User> users = new ArrayList<>(); users.add(new User("张三", "测试1", 12, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); Thread.sleep(1000); users.add(new User("李四", "测试2", 22, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); Thread.sleep(1000); users.add(new User("王五", "测试3", 32, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); Thread.sleep(1000); users.add(new User("赵六", "测试4", 42, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); for (int i = 0; i < users.size(); i++) { //指定id //request.add(new IndexRequest("test_index").id(""+(i+10)).source(JSON.toJSONString(users.get(i)), XContentType.JSON)); //不指定id 后面还可以指定路由.routing("routing") request.add(new IndexRequest("test_index").source(JSON.toJSONString(users.get(i)), XContentType.JSON)); } BulkResponse response = client.bulk(request, RequestOptions.DEFAULT); System.out.println(response); //false代表成功 System.out.println(response.hasFailures()); } //----------------------------------------------------删除文档(单个)---------------------------------------------------- @RequestMapping("/deleteDocument") public void deleteDocument() throws IOException { DeleteRequest request = new DeleteRequest("test_index","kk"); request.timeout("1s"); DeleteResponse response = client.delete(request, RequestOptions.DEFAULT); //OK:删除成功 NOT_FOUND:未发现该id值对应的文档 System.out.println(response.status()); } //----------------------------------------------------查询文档---------------------------------------------------- @RequestMapping("/getDocument") public void getDocument() throws IOException { GetRequest request = new GetRequest("test_index","1"); GetResponse response = client.get(request, RequestOptions.DEFAULT); //没有返回:null //存在返回:{birthday=2020-12-16 16:56:02, full_name=张三李四王五赵六, createTime=1608108962893, name=张三, age=22, isBoy=true, timestamp=1608108962893} System.out.println(response.getSource()); } //---基本查询------------------- //----------------------------------------------------查询所有(match_all)---------------------------------------------------- @RequestMapping("/matchAllDocument") public void matchAllDocument() throws IOException { //1,构建SearchRequest请求对象,指定索引库 SearchRequest request = new SearchRequest("test_index"); //2,构建SearchSourceBuilder查询对象 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //3,构建QueryBuilder对象指定查询方式和查询条件 QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中 sourceBuilder.query(queryBuilder); //5,将SearchSourceBuilder设置到request中 request.source(sourceBuilder); //6,调用方法查询数据 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //7,解析返回结果 SearchHit[] hits = response.getHits().getHits(); //8. 返回查询数量 14 hits System.out.println(response.getHits().getTotalHits()); for (int i = 0; i < hits.length; i++) { //9. 遍历所有数据 getSourceAsString 、getSourceAsMap //{"age":12,"birthday":"2020-12-16 17:15:12","createTime":1608110112784,"full_name":"测试1","isBoy":true,"name":"张三","timestamp":1608110112784} System.out.println(hits[i].getSourceAsString()); //Map<String, Object> sourceAsMap = hits[i].getSourceAsMap(); } } //----------------------------------------------------匹配查询(match)---------------------------------------------------- @RequestMapping("/matchDocument") public void matchDocument() throws IOException { //1,构建SearchRequest请求对象,指定索引库 SearchRequest request = new SearchRequest("test_index"); //2,构建SearchSourceBuilder查询对象 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //3,构建QueryBuilder对象指定查询方式和查询条件 QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "张三"); //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中 sourceBuilder.query(queryBuilder); //5,将SearchSourceBuilder设置到SearchRequest中 request.source(sourceBuilder); //6,调用方法查询数据 SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); //7,解析返回结果 SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------多字段查询(multi_match)---------------------------------------------------- @RequestMapping("/multiMatchDocument") public void multiMatchDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //第一个参数是查询的值,后面的参数是字段名,可以跟多个字段,用逗号隔开 QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("李四", "name", "full_name"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------词条精确匹配(term)---------------------------------------------------- @RequestMapping("/termDocument") public void termDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "王五"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------多词条精确匹配(terms)---------------------------------------------------- @RequestMapping("/termsDocument") public void termsDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders.termsQuery("age", "22", "45"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } //写法2: // SearchRequest request = new SearchRequest("test_index"); // SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("age", "22", "45"); // sourceBuilder.query(termsQueryBuilder); // request.source(sourceBuilder); // SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); // SearchHit[] hits = searchResponse.getHits().getHits(); // for (int i = 0; i <hits.length ; i++) { // System.out.println("返回的结果: "+hits[i].getSourceAsString()); // } } //---高级查询------------------- //----------------------------------------------------布尔组合(bool)---------------------------------------------------- //`bool`把各种其它查询通过`must`(与)、`must_not`(非)、`should`(或)的方式进行组合 @RequestMapping("/boolDocument") public void boolDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询name字段值为李四或者王五的数据 // QueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("name", "王五"); // QueryBuilder matchQueryBuilder2 = QueryBuilders.matchQuery("name", "李四"); // BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // boolQueryBuilder.should(matchQueryBuilder1); // boolQueryBuilder.should(matchQueryBuilder2); //查询name字段值为张三且age字段为22的 // QueryBuilder matchQueryBuilder3 = QueryBuilders.matchQuery("name", "张三"); // QueryBuilder matchQueryBuilder4 = QueryBuilders.matchQuery("age", "22"); // BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // boolQueryBuilder.must(matchQueryBuilder3); // boolQueryBuilder.must(matchQueryBuilder4); //查询name字段值不等于张三和李四的数据 QueryBuilder matchQueryBuilder5 = QueryBuilders.matchQuery("name", "张三"); QueryBuilder matchQueryBuilder6 = QueryBuilders.matchQuery("name", "李四"); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.mustNot(matchQueryBuilder5); boolQueryBuilder.mustNot(matchQueryBuilder6); sourceBuilder.query(boolQueryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------范围查询(range)---------------------------------------------------- //`range` 查询找出那些落在指定区间内的数字或者时间 gt gte lt lte @RequestMapping("/rangeDocument") public void rangeDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询age字段大于22小于43的 //QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gt("22").lt("43"); //查询birthday字段时间在2020-12-16 16:00:00~~~2020-12-16 17:00:00范围的 QueryBuilder queryBuilder = QueryBuilders.rangeQuery("birthday").gte("2020-12-16 16:00:00").lte("2020-12-16 17:00:00"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------前缀查询(prefix)---------------------------------------------------- @RequestMapping("/prefixDocument") public void prefixDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询full_name字段以张三开头的数据 QueryBuilder queryBuilder = QueryBuilders.prefixQuery("full_name","张三"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------模糊查询(wildcard)---------------------------------------------------- @RequestMapping("/wildcardDocument") public void wildcardDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询full_name字段以测试开头的数据 //QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "测试*"); //查询full_name字段以1结尾的数据 QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "*1"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------模糊查询(fuzzy)---------------------------------------------------- @RequestMapping("/fuzzyDocument") public void fuzzyDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //模糊查询full_name字段值为测试1的数据 fuzzy允许有一定程度的不同 所以尽管数据库中数据是测试1 仍可以搜索出来 QueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("full_name", "测测1"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------排序单字段、多字段(sort)---------------------------------------------------- @RequestMapping("/sortDocument") public void sortDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000); //先按照age进行正排序,之后age字段相同的再按照birthday字段倒排序 sourceBuilder.query(queryBuilder).sort("age", SortOrder.ASC).sort("birthday",SortOrder.DESC); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------分页(from、size)---------------------------------------------------- @RequestMapping("/fromSizeDocument") public void fromSizeDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000); //查询从第一条开始(包括)查询两条数据(结果为查询前两条数据) sourceBuilder.query(queryBuilder).from(0).size(2); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------高亮(high light)---------------------------------------------------- @RequestMapping("/highLightDocument") public void highLightDocument() throws IOException { //条件搜索 SearchRequest goods = new SearchRequest("test_index"); SearchSourceBuilder builder = new SearchSourceBuilder(); TermQueryBuilder title = QueryBuilders.termQuery("name", "李四"); builder.query(title); builder.timeout(new TimeValue(60, TimeUnit.SECONDS)); HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("name");//高亮的字段 highlightBuilder.requireFieldMatch(false);//是否多个字段都高亮 highlightBuilder.preTags("<span style='color:red'>");//前缀后缀 highlightBuilder.postTags("</span>"); builder.highlighter(highlightBuilder); //执行搜索 goods.source(builder); SearchResponse search = client.search(goods, RequestOptions.DEFAULT); //解析结果 ArrayList<Map<String,Object>> list = new ArrayList<>(); for (SearchHit hit : search.getHits().getHits()) { //解析高亮的字段 //获取高亮字段 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); HighlightField name = highlightFields.get("name"); Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果 //将原来的字段替换为高亮字段即可 if (name!=null){ Text[] fragments = name.fragments(); String newTitle = ""; for (Text text : fragments) { newTitle +=text; } sourceAsMap.put("name",newTitle);//替换掉原来的内容 } list.add(sourceAsMap); } System.out.println(list); } }
三、Kibana对应操作
1. 查看某个索引是否存在及该索引信息
//-------------------------------------------------查看索引是否存在------------------------------------------------ @RequestMapping("/existIndex") public boolean existIndex() throws IOException { GetIndexRequest request = new GetIndexRequest("test_index"); boolean exists = client.indices().exists(request, RequestOptions.DEFAULT); return exists; } //----------------------------------------------------查看索引信息---------------------------------------------------- @RequestMapping("/getIndex") public void getIndex() throws IOException { GetIndexRequest request = new GetIndexRequest("test_index"); GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT); //获取索引信息 Map<String, List<AliasMetaData>> aliases = response.getAliases(); Map<String, MappingMetaData> mappings = response.getMappings(); Map<String, Settings> settings = response.getSettings(); }
#查看索引结构 索引存在 GET /test_index #结果 { "test_index" : { "aliases" : { }, "mappings" : { "properties" : { "age" : { "type" : "integer" }, "birthday" : { "type" : "date", "format" : "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }, "createTime" : { "type" : "date", "format" : "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }, "full_name" : { "type" : "keyword" }, "isBoy" : { "type" : "boolean" }, "name" : { "type" : "text", "analyzer" : "ik_max_word" }, "timestamp" : { "type" : "long" } } }, "settings" : { "index" : { "creation_date" : "1608107781691", "number_of_shards" : "1", "number_of_replicas" : "1", "uuid" : "8u48j3MsQEuPy90fcYkcuA", "version" : { "created" : "7060199" }, "provided_name" : "test_index" } } } } #查看索引结构 索引不存在 GET /test_index2 #结果 { "error" : { "root_cause" : [ { "type" : "index_not_found_exception", "reason" : "no such index [test_index2]", "resource.type" : "index_or_alias", "resource.id" : "test_index2", "index_uuid" : "_na_", "index" : "test_index2" } ], "type" : "index_not_found_exception", "reason" : "no such index [test_index2]", "resource.type" : "index_or_alias", "resource.id" : "test_index2", "index_uuid" : "_na_", "index" : "test_index2" }, "status" : 404 }
2. 查看所有索引
//----------------------------------------------------查看所有索引信息---------------------------------------------------- @RequestMapping("/getAllIndex") public void getAllIndex() throws IOException { //查看所有索引信息 //GetIndexRequest request = new GetIndexRequest("*"); //查看符合条件的索引信息 GetIndexRequest request = new GetIndexRequest("test_*"); GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT); String[] indices = response.getIndices(); }
#查看所有索引
GET _cat/indices
#结果
yellow open test_index3 4Jo-ITT4Rma_u-y3KRhokA 1 1 0 0 230b 230b
green open .kibana_task_manager_1 sT-xQclUT-Obsg2H8DC9pQ 1 0 2 0 31.6kb 31.6kb
yellow open test_index1 vcuSyzX3ThKKVq8GzHUpag 1 1 0 0 283b 283b
green open .apm-agent-configuration fjiQqCgbQ1CVBvBK1J8TMA 1 0 0 0 283b 283b
yellow open test_index 8u48j3MsQEuPy90fcYkcuA 1 1 14 1 30kb 30kb
green open .kibana_1 oILjMxaTQGaVyBHK94jdrQ 1 0 43 7 62.5kb 62.5kb
Kibana操作
3. 创建索引:
{ CreateIndexRequest request = new CreateIndexRequest("test_index"); client.indices().createAsync(request, RequestOptions.DEFAULT, new ActionListener<CreateIndexResponse>() { @Override public void onResponse(CreateIndexResponse createIndexResponse) { log.debug("执行情况:" + createIndexResponse); System.out.println(createIndexResponse); } @Override public void onFailure(Exception e) { log.error("执行失败的原因:" + e.getMessage()) ; System.out.println(e.getMessage()); } }); }
#创建索引
PUT /test_index3
{
"aliases": {},
"mappings": {
"properties": {
"age": {
"type": "integer"
},
"birthday": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"createTime": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"full_name": {
"type": "keyword"
},
"isBoy": {
"type": "boolean"
},
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"timestamp": {
"type": "long"
}
}
},
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "1"
}
}
}
#结果
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "test_index3"
}
4. 删除索引
//----------------------------------------------------删除索引---------------------------------------------------- @RequestMapping("/deleteIndex") public boolean deleteIndex() throws IOException { //没有该索引会报错 DeleteIndexRequest request = new DeleteIndexRequest("test_index"); AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT); return delete.isAcknowledged(); }
#删除索引
DELETE /test_index3
#结果
{
"acknowledged" : true
}
5. 更新索引settings和mapping
注意:
1. 更新之前需要关闭索引才可以,否则会报错。
2. 对于mapping的更新,原有的字段及其类型无法更新。只能添加新的字段。
3. 对于settings的更新,目前发现只能更新number_of_replicas。无法更新number_of_shards。
//----------------------------------------------------更新索引settings---------------------------------------------------- @RequestMapping("/updateIndexSettings") public void updateIndexSettings() throws IOException { UpdateSettingsRequest request = new UpdateSettingsRequest("test_index"); Settings.Builder settingsBuilder = Settings.builder().put("index.number_of_replicas", "3"); request.settings(settingsBuilder); // 是否更新已经存在的settings配置 默认false (false的时候可以更新成功 true的时候不成功) //request.setPreserveExisting(false); // 更新settings配置(同步) AcknowledgedResponse acknowledgedResponse = client.indices().putSettings(request, RequestOptions.DEFAULT); System.out.println(acknowledgedResponse.isAcknowledged()); } //----------------------------------------------------更新索引mapping---------------------------------------------------- @RequestMapping("/updateIndexMapping") public void updateIndexMapping() throws IOException { //这里要注意:已经创建好的文档字段不能删除和更改类型以及里面的属性,但是可以添加字段, //如果想要修改,需要新创建一个索引,之后将原索引中的数据同步过去,指定别名,最后删除原索引 PutMappingRequest request = new PutMappingRequest("test_index"); XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); { builder.startObject("properties"); { //String text 分词 builder.startObject("name"); { builder.field("type","text"); builder.field("analyzer", "ik_max_word"); } builder.endObject(); //String keyword 不分词 builder.startObject("full_name"); { builder.field("type","keyword"); } builder.endObject(); //Numeric integer builder.startObject("age"); { builder.field("type","integer"); } builder.endObject(); //Date date builder.startObject("birthday"); { builder.field("type","date"); builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"); } builder.endObject(); //Data date builder.startObject("createTime"); { builder.field("type","date"); builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"); } builder.endObject(); //Numeric long builder.startObject("timestamp"); { builder.field("type","long"); } builder.endObject(); //Boolean boolean builder.startObject("isBoy"); { builder.field("type","boolean"); } builder.endObject(); } builder.endObject(); } builder.endObject(); request.source(builder); // 新增mapping配置(同步) AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT); System.out.println(response); }
#关闭索引
POST /test_index3/_close
#结果
{
"acknowledged" : true,
"shards_acknowledged" : true,
"indices" : {
"test_index3" : {
"closed" : true
}
}
}
#打开索引
POST /test_index3/_open
#结果
{
"acknowledged" : true,
"shards_acknowledged" : true
}
#修改settings
PUT /test_index3/_settings
{
"number_of_replicas": 2
}
#修改mappings
PUT /test_index3/_mappings
{
"properties": {
"test":{
"type":"text"
}
}
}
#结果
{
"acknowledged" : true
}
6. 添加文档(单个/多个 同步+异步)
//----------------------------------------------------添加文档(单个 同步+异步)---------------------------------------------------- @RequestMapping("/addDocument") public void addDocument() throws IOException { User user = new User(); user.setName("张三"); user.setFull_name("张三李四王五赵六"); user.setAge(12); user.setIsBoy(true); user.setTimestamp(System.currentTimeMillis());//存入的是毫秒值1608108501654 user.setCreateTime(new Date());//存入的是毫秒值1608108501654 user.setBirthday(LocalDateTime.now());////存入的是时间格式2020-12-16 16:48:21 IndexRequest request = new IndexRequest("test_index"); // 规则 put /test_index/_doc/1 //不指定id会随机生成 有该id会更新 没有该id会添加 //request.id("1"); request.timeout(TimeValue.timeValueSeconds(1)); request.source(JSON.toJSONString(user), XContentType.JSON); //同步 IndexResponse response = client.index(request, RequestOptions.DEFAULT); // 结果:IndexResponse[index=test_index,type=_doc,id=nGvFanYBf998z9yKoZFx,version=1,result=created,seqNo=3,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}] System.out.println(response.toString()); //新建:CREATED 更新:OK System.out.println(response.status()); //异步 // Cancellable cancellable = client.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() { // @Override // public void onResponse(IndexResponse indexResponse) { // //这里可以获取添加的数据 // log.debug("执行情况: " + indexResponse); // } // // @Override // public void onFailure(Exception e) { // log.error("执行失败的原因"); // } // }); } //----------------------------------------------------添加文档(单个 map方式)---------------------------------------------------- @RequestMapping("/addDocumentByMap") public void addDocumentByMap() throws IOException { Map<String, Object> map = new HashMap<>(); map.put("name", "张三"); map.put("full_name", "测试测试"); map.put("age", 45); map.put("birthday", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now())); map.put("createTime", System.currentTimeMillis()); map.put("timestamp", System.currentTimeMillis()); map.put("isBoy", false); IndexRequest request = new IndexRequest("test_index"); request.id("kk"); request.source(map); IndexResponse response = client.index(request, RequestOptions.DEFAULT); System.out.println(response.status()); } //----------------------------------------------------添加文档(批量)---------------------------------------------------- @RequestMapping("/addBulkDocument") public void addBulkDocument() throws Exception { BulkRequest request = new BulkRequest(); request.timeout("15s"); List<User> users = new ArrayList<>(); users.add(new User("张三", "测试1", 12, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); Thread.sleep(1000); users.add(new User("李四", "测试2", 22, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); Thread.sleep(1000); users.add(new User("王五", "测试3", 32, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); Thread.sleep(1000); users.add(new User("赵六", "测试4", 42, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true)); for (int i = 0; i < users.size(); i++) { //指定id //request.add(new IndexRequest("test_index").id(""+(i+10)).source(JSON.toJSONString(users.get(i)), XContentType.JSON)); //不指定id 后面还可以指定路由.routing("routing") request.add(new IndexRequest("test_index").source(JSON.toJSONString(users.get(i)), XContentType.JSON)); } BulkResponse response = client.bulk(request, RequestOptions.DEFAULT); System.out.println(response); //false代表成功 System.out.println(response.hasFailures()); }
#添加文档(指定id)
POST /test_index3/_doc/2
{
"age":1
}
#结果
{
"_index" : "test_index3",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 3,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 8
}
#添加文档(不指定id-->随机生成)
POST /test_index3/_doc
{
"age":2
}
#结果
{
"_index" : "test_index3",
"_type" : "_doc",
"_id" : "ZKlVzXYB6Pl4va605fxV",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 3,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 4,
"_primary_term" : 8
}
#批量添加
POST _bulk
{"index":{"_index":"test_index3","_id":"7"}}
{"age":7}
{"index":{"_index":"test_index3","_id":"8"}}
{"age":8}
{"index":{"_index":"test_index3","_id":"9"}}
{"age":9}
7. 删除文档
//----------------------------------------------------删除文档(单个)---------------------------------------------------- @RequestMapping("/deleteDocument") public void deleteDocument() throws IOException { DeleteRequest request = new DeleteRequest("test_index","kk"); request.timeout("1s"); DeleteResponse response = client.delete(request, RequestOptions.DEFAULT); //OK:删除成功 NOT_FOUND:未发现该id值对应的文档 System.out.println(response.status()); }
#删除文档
DELETE /test_index3/_doc/9
#结果
{
"_index" : "test_index3",
"_type" : "_doc",
"_id" : "9",
"_version" : 3,
"result" : "deleted",
"_shards" : {
"total" : 3,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 12,
"_primary_term" : 8
}
8. 查询文档
//----------------------------------------------------查询文档---------------------------------------------------- @RequestMapping("/getDocument") public void getDocument() throws IOException { GetRequest request = new GetRequest("test_index","1"); GetResponse response = client.get(request, RequestOptions.DEFAULT); //没有返回:null //存在返回:{birthday=2020-12-16 16:56:02, full_name=张三李四王五赵六, createTime=1608108962893, name=张三, age=22, isBoy=true, timestamp=1608108962893} System.out.println(response.getSource()); }
#查看文档
GET /test_index3/_doc/7
#结果
{
"_index" : "test_index3",
"_type" : "_doc",
"_id" : "7",
"_version" : 2,
"_seq_no" : 9,
"_primary_term" : 8,
"found" : true,
"_source" : {
"age" : 7
}
}
四、基本查询
1. 查询所有(match_all)
//----------------------------------------------------查询所有(match_all)---------------------------------------------------- @RequestMapping("/matchAllDocument") public void matchAllDocument() throws IOException { //1,构建SearchRequest请求对象,指定索引库 SearchRequest request = new SearchRequest("test_index"); //2,构建SearchSourceBuilder查询对象 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //3,构建QueryBuilder对象指定查询方式和查询条件 QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中 sourceBuilder.query(queryBuilder); //5,将SearchSourceBuilder设置到request中 request.source(sourceBuilder); //6,调用方法查询数据 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //7,解析返回结果 SearchHit[] hits = response.getHits().getHits(); //8. 返回查询数量 14 hits System.out.println(response.getHits().getTotalHits()); for (int i = 0; i < hits.length; i++) { //9. 遍历所有数据 getSourceAsString 、getSourceAsMap //{"age":12,"birthday":"2020-12-16 17:15:12","createTime":1608110112784,"full_name":"测试1","isBoy":true,"name":"张三","timestamp":1608110112784} System.out.println(hits[i].getSourceAsString()); //Map<String, Object> sourceAsMap = hits[i].getSourceAsMap(); } }
#查看所有
GET /test_index3/_search
{
"query": {
"match_all": {}
}
}
#结果
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index3",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"age" : 1
}
},
{
"_index" : "test_index3",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"age" : 1
}
}
]
}
}
2. 按条件查询match
//----------------------------------------------------匹配查询(match)---------------------------------------------------- @RequestMapping("/matchDocument") public void matchDocument() throws IOException { //1,构建SearchRequest请求对象,指定索引库 SearchRequest request = new SearchRequest("test_index"); //2,构建SearchSourceBuilder查询对象 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //3,构建QueryBuilder对象指定查询方式和查询条件 QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "张三"); //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中 sourceBuilder.query(queryBuilder); //5,将SearchSourceBuilder设置到SearchRequest中 request.source(sourceBuilder); //6,调用方法查询数据 SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); //7,解析返回结果 SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#按条件查看
GET /test_index/_search
{
"query": {
"match": {
"name": "赵六"
}
}
}
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 3.712596,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "13",
"_score" : 3.712596,
"_source" : {
"age" : 42,
"birthday" : "2020-12-16 17:15:15",
"createTime" : 1608110115801,
"full_name" : "测试4",
"isBoy" : true,
"name" : "赵六",
"timestamp" : 1608110115801
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "oWvVanYBf998z9yKDJHM",
"_score" : 3.712596,
"_source" : {
"age" : 42,
"birthday" : "2020-12-16 17:15:15",
"createTime" : 1608110115801,
"full_name" : "测试4",
"isBoy" : true,
"name" : "赵六",
"timestamp" : 1608110115801
}
}
]
}
}
3. 单、多词条精确查询term、terms
//----------------------------------------------------词条精确匹配(term)---------------------------------------------------- @RequestMapping("/termDocument") public void termDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "王五"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } } //----------------------------------------------------多词条精确匹配(terms)---------------------------------------------------- @RequestMapping("/termsDocument") public void termsDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders.termsQuery("age", "22", "45"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } //写法2: // SearchRequest request = new SearchRequest("test_index"); // SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("age", "22", "45"); // sourceBuilder.query(termsQueryBuilder); // request.source(sourceBuilder); // SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); // SearchHit[] hits = searchResponse.getHits().getHits(); // for (int i = 0; i <hits.length ; i++) { // System.out.println("返回的结果: "+hits[i].getSourceAsString()); // } }
#term
GET /test_index/_search
{
"query": {
"term": {
"age": {
"value": "42"
}
}
}
}
#terms
GET /test_index/_search
{
"query": {
"terms": {
"age": [22,42]
}
}
}
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "13",
"_score" : 1.0,
"_source" : {
"age" : 42,
"birthday" : "2020-12-16 17:15:15",
"createTime" : 1608110115801,
"full_name" : "测试4",
"isBoy" : true,
"name" : "赵六",
"timestamp" : 1608110115801
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "oWvVanYBf998z9yKDJHM",
"_score" : 1.0,
"_source" : {
"age" : 42,
"birthday" : "2020-12-16 17:15:15",
"createTime" : 1608110115801,
"full_name" : "测试4",
"isBoy" : true,
"name" : "赵六",
"timestamp" : 1608110115801
}
}
]
}
}
4. 布尔组合查询bool
bool把各种其它查询通过must(与)、must_not(非)、should(或)的方式进行组合
//----------------------------------------------------布尔组合(bool)---------------------------------------------------- //`bool`把各种其它查询通过`must`(与)、`must_not`(非)、`should`(或)的方式进行组合 @RequestMapping("/boolDocument") public void boolDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询name字段值为李四或者王五的数据 // QueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("name", "王五"); // QueryBuilder matchQueryBuilder2 = QueryBuilders.matchQuery("name", "李四"); // BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // boolQueryBuilder.should(matchQueryBuilder1); // boolQueryBuilder.should(matchQueryBuilder2); //查询name字段值为张三且age字段为22的 // QueryBuilder matchQueryBuilder3 = QueryBuilders.matchQuery("name", "张三"); // QueryBuilder matchQueryBuilder4 = QueryBuilders.matchQuery("age", "22"); // BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // boolQueryBuilder.must(matchQueryBuilder3); // boolQueryBuilder.must(matchQueryBuilder4); //查询name字段值不等于张三和李四的数据 QueryBuilder matchQueryBuilder5 = QueryBuilders.matchQuery("name", "张三"); QueryBuilder matchQueryBuilder6 = QueryBuilders.matchQuery("name", "李四"); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.mustNot(matchQueryBuilder5); boolQueryBuilder.mustNot(matchQueryBuilder6); sourceBuilder.query(boolQueryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#bool
GET /test_index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"name": "张三"
}
},
{
"term": {
"age":"45"
}
}
]
}
}
}
#结果
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.5212969,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "NstqbnYB2MS8XlkB1n68",
"_score" : 1.5212969,
"_source" : {
"full_name" : "测试测试",
"createTime" : 1608170259651,
"name" : "张三",
"age" : 45,
"isBoy" : false,
"timestamp" : 1608170259651
}
}
]
}
}
5. 范围查询range
//----------------------------------------------------范围查询(range)---------------------------------------------------- //`range` 查询找出那些落在指定区间内的数字或者时间 gt gte lt lte @RequestMapping("/rangeDocument") public void rangeDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询age字段大于22小于43的 //QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gt("22").lt("43"); //查询birthday字段时间在2020-12-16 16:00:00~~~2020-12-16 17:00:00范围的 QueryBuilder queryBuilder = QueryBuilders.rangeQuery("birthday").gte("2020-12-16 16:00:00").lte("2020-12-16 17:00:00"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#range
GET /test_index/_search
{
"query": {
"range": {
"age": {
"gte": 43,
"lte": 45
}
}
}
}
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "NstqbnYB2MS8XlkB1n68",
"_score" : 1.0,
"_source" : {
"full_name" : "测试测试",
"createTime" : 1608170259651,
"name" : "张三",
"age" : 45,
"isBoy" : false,
"timestamp" : 1608170259651
}
}
]
}
}
6. 前缀查询prefix
//----------------------------------------------------前缀查询(prefix)---------------------------------------------------- @RequestMapping("/prefixDocument") public void prefixDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询full_name字段以张三开头的数据 QueryBuilder queryBuilder = QueryBuilders.prefixQuery("full_name","张三"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#prefix
GET /test_index/_search
{
"query": {
"prefix": {
"name": "王"
}
}
}
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "12",
"_score" : 1.0,
"_source" : {
"age" : 32,
"birthday" : "2020-12-16 17:15:14",
"createTime" : 1608110114796,
"full_name" : "测试3",
"isBoy" : true,
"name" : "王五",
"timestamp" : 1608110114796
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "oGvVanYBf998z9yKDJHM",
"_score" : 1.0,
"_source" : {
"age" : 32,
"birthday" : "2020-12-16 17:15:14",
"createTime" : 1608110114796,
"full_name" : "测试3",
"isBoy" : true,
"name" : "王五",
"timestamp" : 1608110114796
}
}
]
}
}
7. 模糊查询wildcard
//----------------------------------------------------模糊查询(wildcard)---------------------------------------------------- @RequestMapping("/wildcardDocument") public void wildcardDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询full_name字段以测试开头的数据 //QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "测试*"); //查询full_name字段以1结尾的数据 QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "*1"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#wildcard
GET /test_index/_search
{
"query": {
"wildcard": {
"full_name": "*试测*"
}
}
}
#结果
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "NstqbnYB2MS8XlkB1n68",
"_score" : 1.0,
"_source" : {
"full_name" : "测试测试",
"createTime" : 1608170259651,
"name" : "张三",
"age" : 45,
"isBoy" : false,
"timestamp" : 1608170259651
}
}
]
}
}
8. 模糊查询fuzzy
//----------------------------------------------------模糊查询(fuzzy)---------------------------------------------------- @RequestMapping("/fuzzyDocument") public void fuzzyDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //模糊查询full_name字段值为测试1的数据 fuzzy允许有一定程度的不同 所以尽管数据库中数据是测试1 仍可以搜索出来 QueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("full_name", "测测1"); sourceBuilder.query(queryBuilder); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#wildcard
GET /test_index/_search
{
"query": {
"fuzzy": {
"name": {
"value": "李四",
"fuzziness": 0,
"prefix_length": 0,
"max_expansions": 50,
"transpositions": true
}
}
}
}
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.856298,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "11",
"_score" : 1.856298,
"_source" : {
"age" : 22,
"birthday" : "2020-12-16 17:15:13",
"createTime" : 1608110113788,
"full_name" : "测试2",
"isBoy" : true,
"name" : "李四",
"timestamp" : 1608110113788
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "n2vVanYBf998z9yKDJHM",
"_score" : 1.856298,
"_source" : {
"age" : 22,
"birthday" : "2020-12-16 17:15:13",
"createTime" : 1608110113788,
"full_name" : "测试2",
"isBoy" : true,
"name" : "李四",
"timestamp" : 1608110113788
}
}
]
}
}
9. 单、多字段排序sort
//----------------------------------------------------排序单字段、多字段(sort)---------------------------------------------------- @RequestMapping("/sortDocument") public void sortDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000); //先按照age进行正排序,之后age字段相同的再按照birthday字段倒排序 sourceBuilder.query(queryBuilder).sort("age", SortOrder.ASC).sort("birthday",SortOrder.DESC); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#wildcard
GET /test_index/_search
{
"query": {
"match": {
"name": "张三"
}
},
"sort": [
{
"timestamp": {
"order": "desc"
},
"birthday": {
"order": "desc"
}
}
]
}
#结果
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 8,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "NstqbnYB2MS8XlkB1n68",
"_score" : null,
"_source" : {
"full_name" : "测试测试",
"createTime" : 1608170259651,
"name" : "张三",
"age" : 45,
"isBoy" : false,
"timestamp" : 1608170259651
},
"sort" : [
1608170259651,
9223372036854775807
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "o2vranYBf998z9yKX5HG",
"_score" : null,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 17:39:04",
"createTime" : 1608111544743,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608111544743
},
"sort" : [
1608111544743,
1608140344000
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "omvoanYBf998z9yKeJGS",
"_score" : null,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 17:36:28",
"createTime" : 1608111388649,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608111388649
},
"sort" : [
1608111388649,
1608140188000
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "10",
"_score" : null,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 17:15:12",
"createTime" : 1608110112784,
"full_name" : "测试1",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608110112784
},
"sort" : [
1608110112784,
1608138912000
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "nmvVanYBf998z9yKDJHL",
"_score" : null,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 17:15:12",
"createTime" : 1608110112784,
"full_name" : "测试1",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608110112784
},
"sort" : [
1608110112784,
1608138912000
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "nWvGanYBf998z9yKv5Gv",
"_score" : null,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 16:59:38",
"createTime" : 1608109178797,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608109178797
},
"sort" : [
1608109178797,
1608137978000
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "nGvFanYBf998z9yKoZFx",
"_score" : null,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 16:58:25",
"createTime" : 1608109105356,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608109105356
},
"sort" : [
1608109105356,
1608137905000
]
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : null,
"_source" : {
"age" : 22,
"birthday" : "2020-12-16 16:56:02",
"createTime" : 1608108962893,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608108962893
},
"sort" : [
1608108962893,
1608137762000
]
}
]
}
}
10. 分页from size
//----------------------------------------------------分页(from、size)---------------------------------------------------- @RequestMapping("/fromSizeDocument") public void fromSizeDocument() throws IOException { SearchRequest request = new SearchRequest("test_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000); //查询从第一条开始(包括)查询两条数据(结果为查询前两条数据) sourceBuilder.query(queryBuilder).from(0).size(2); request.source(sourceBuilder); SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); for (int i = 0; i <hits.length ; i++) { System.out.println("返回的结果: "+hits[i].getSourceAsString()); } }
#from size
GET /test_index/_search
{
"query": {
"match": {
"name": "张三"
}
},
"from": 0,
"size": 2
}
#结果
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 8,
"relation" : "eq"
},
"max_score" : 1.0425937,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0425937,
"_source" : {
"age" : 22,
"birthday" : "2020-12-16 16:56:02",
"createTime" : 1608108962893,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608108962893
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "nGvFanYBf998z9yKoZFx",
"_score" : 1.0425937,
"_source" : {
"age" : 12,
"birthday" : "2020-12-16 16:58:25",
"createTime" : 1608109105356,
"full_name" : "张三李四王五赵六",
"isBoy" : true,
"name" : "张三",
"timestamp" : 1608109105356
}
}
]
}
}
11. 高亮high light
//----------------------------------------------------高亮(high light)---------------------------------------------------- @RequestMapping("/highLightDocument") public void highLightDocument() throws IOException { //条件搜索 SearchRequest goods = new SearchRequest("test_index"); SearchSourceBuilder builder = new SearchSourceBuilder(); TermQueryBuilder title = QueryBuilders.termQuery("name", "李四"); builder.query(title); builder.timeout(new TimeValue(60, TimeUnit.SECONDS)); HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("name");//高亮的字段 highlightBuilder.requireFieldMatch(false);//是否多个字段都高亮 highlightBuilder.preTags("<span style='color:red'>");//前缀后缀 highlightBuilder.postTags("</span>"); builder.highlighter(highlightBuilder); //执行搜索 goods.source(builder); SearchResponse search = client.search(goods, RequestOptions.DEFAULT); //解析结果 ArrayList<Map<String,Object>> list = new ArrayList<>(); for (SearchHit hit : search.getHits().getHits()) { //解析高亮的字段 //获取高亮字段 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); HighlightField name = highlightFields.get("name"); Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果 //将原来的字段替换为高亮字段即可 if (name!=null){ Text[] fragments = name.fragments(); String newTitle = ""; for (Text text : fragments) { newTitle +=text; } sourceAsMap.put("name",newTitle);//替换掉原来的内容 } list.add(sourceAsMap); } System.out.println(list); }
持续更新!!!