irpas技术客

java操作es之各种高级查询_走进IT_es java 查询

大大的周 6634

目录 一、springboot整合es1.1 pom依赖1.2 yml配置1.3 创建索引1.4 创建映射1.5 写入数据 二、Java API操作ES2.1 查询全部2.2 精准匹配2.3 全文检索 MatchQuery2.4 多字段联合搜索 MultiQuery2.5 布尔查询 BoolQuery2.6 模糊匹配WildcardQuery2.7 范围匹配RangeQuery2.8 分页查询 三、 过滤四、 排序五、 高亮

一、springboot整合es

本节主要内容是使用ES客户端链接: Java High Level REST Client操作ES(推荐使用该客户端)。

1.1 pom依赖 <!-- ES 客户端 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.9.1</version> </dependency> <!-- ES 版本 --> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.9.1</version> </dependency> 1.2 yml配置 spring: elasticsearch: rest: uris: 127.0.0.1:9200 read-timeout: 60s 1.3 创建索引

address

1.4 创建映射 put http://localhost:9200/address/_mapping { "properties": { "name": { "type": "text", "analyzer": "ik_max_word", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "address": { "type": "text" }, "location": { "type": "keyword" }, "type": { "type": "keyword" }, "geom": { "type": "geo_shape" }, "timestamp": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } 1.5 写入数据 PUT address/_docs/1000 { "name": "spring开发", "address":"北京市朝阳区和平街", "type":"餐饮", "location":"121.392496,31.245827", "geom": { "type": "point", "coordinates": [121.392496,31.245827] }, "timestamp":"2021-04-25 19:11:35" } 二、Java API操作ES 2.1 查询全部 // 搜索全部记录 @Test public void testSearchAll() throws IOException, ParseException { // 搜索请求对象 SearchRequest searchRequest = new SearchRequest("address"); // 指定类型 searchRequest.types("_doc"); // 搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 搜索方式 // matchAllQuery搜索全部 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); // 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段 searchSourceBuilder.fetchSource(new String[]{"name","address","location","timestamp"},new String[]{}); // 向搜索请求对象中设置搜索源 searchRequest.source(searchSourceBuilder); // 执行搜索,向ES发起http请求 SearchResponse searchResponse = client.search(searchRequest); // 搜索结果 SearchHits hits = searchResponse.getHits(); // 匹配到的总记录数 long totalHits = hits.getTotalHits(); // 得到匹配度高的文档 SearchHit[] searchHits = hits.getHits(); // 日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ // 文档的主键 String id = hit.getId(); // 源文档内容 Map<String, Object> sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name"); // 日期 Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); } } 2.2 精准匹配

Term Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词 DSL:

{ "query": { "term": { // 查询的方式为 term 精确查询 "name": "spring" // 查询的字段为 name 关键字是 spring } } }

java api:

// 搜索方式 // termQuery 精确查询 searchSourceBuilder.query(QueryBuilders.termQuery("name", "spring开发")); 2.3 全文检索 MatchQuery

MatchQuery 即全文检索,会对关键字进行分词后匹配词条。

query:搜索的关键字,对于英文关键字如果有多个单词则中间要用半角逗号分隔,而对于中文关键字中间可以用 逗号分隔也可以不用

operator:设置查询的结果取交集还是并集,并集用 or, 交集用 and DSL:

{ "query": { "match": { "description": { "query": "spring开发", "operator": "or" } } } }

java api

// matchQuery全文检索 searchSourceBuilder.query(QueryBuilders.matchQuery("name", "Spring开发框架")); 2.4 多字段联合搜索 MultiQuery

MultiQuery可以通过 fields 属性来设置多个域联合查找。 DSL:

{ "query": { "multi_match": { "query": "Spring开发框架", "minimum_should_match": "80%", "fields": ["name", "description"] } } }

java api:

searchSourceBuilder.query(QueryBuilders.multiMatchQuery("Spring开发框架", "name", "address").minimumShouldMatch("80%"));

注:“spring开发框架”会被分为三个词:spring、开发、框架 设置"minimum_should_match": "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向下取整得2,表示至少有两个词在文档中要匹配成功。 提升boost: 在多域联合查询的时候,可以通过 boost 来设置某个域在计算得分时候的比重,比重越高的域当他符合条件时计算的得分越高,相应的该记录也更靠前。通过在 fields 中给相应的字段用 ^权重倍数来实现。 DSL:

"fields": ["name^10", "address"]

java链式编程:

searchSourceBuilder.query(QueryBuilders.multiMatchQuery("Spring开发框架", "name", "address").field("name", 10)); // 设置 name 10倍权重 2.5 布尔查询 BoolQuery

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来,有三个可选的参数:

must: 文档必须匹配must所包括的查询条件,相当于 “AND” should: 文档应该匹配should所包括的查询条件其中的一个或多个,相当于 “OR” must_not: 文档不能匹配must_not所包括的该查询条件,相当于“NOT”

DSL:

{ "query": { "bool": { // 布尔查询 "must": [ // 查询条件 must 表示数组中的查询方式所规定的条件都必须满足 { "multi_match": { "query": "spring框架", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } }, { "term": { "type": "餐饮" } } ] } } }

java api:

// 首先构造多关键字查询条件 MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("Spring开发框架", "name", "address").field("name", 10); // 然后构造精确匹配查询条件 TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("type", "201002"); // 组合两个条件,组合方式为 must 全满足 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(matchQueryBuilder); boolQueryBuilder.must(termQueryBuilder); // 将查询条件封装给查询对象 searchSourceBuilder.query(boolQueryBuilder); 2.6 模糊匹配WildcardQuery

对于es关键字或单词的查询我们可以借助QueryBuilders.wildcardQuery方法来操作,只需要指定es中对应的列和要查询的内容即可:

boolQueryBuilder.must(QueryBuilders.wildcardQuery("name", "spring"+"*")); 2.7 范围匹配RangeQuery

例如:

boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100)); 2.8 分页查询 // 设置查询的起始位置,默认是0 sourceBuilder.from(0); // 设置查询结果的页大小,默认是10 sourceBuilder.size(10); 三、 过滤

定义过滤器查询,是在原本查询结果的基础上对数据进行筛选,因此省略了重新计算的分的步骤,效率更高。并且方便缓存。推荐尽量使用过虑器去实现查询或者过虑器和查询共同使用,过滤器在布尔查询中使用。

boolQueryBuilder.filter(QueryBuilders.termQuery("type", "餐饮")); 四、 排序

SearchSourceBuilder允许增加一或多个排序参数SortBuilder,有四个具体实现FieldSortBuilder, ScoreSortBuilder, GeoDistanceSortBuilder 和 ScriptSortBuilder。 注:支持对 keyword、date、float 等类型添加排序,text类型的字段不允许排序。

// 默认排序。根据_score倒序 sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); // 根据_id升序 sourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC)); searchBuilder.sort("type", SortOrder.DESC); 五、 高亮 // 高亮查询 @Test public void testHighLight() throws IOException, ParseException { // 搜索请求对象 SearchRequest searchRequest = new SearchRequest("ysx_course"); // 指定类型 searchRequest.types("doc"); // 搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 搜索方式 // 首先构造多关键字查询条件 MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("Spring框架", "name", "address").field("name", 10); // 添加条件到布尔查询 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(matchQueryBuilder); // 将查询条件封装给查询对象 searchSourceBuilder.query(boolQueryBuilder); // *********************** // 高亮查询 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("<em>"); // 高亮前缀 highlightBuilder.postTags("</em>"); // 高亮后缀 highlightBuilder.fields().add(new HighlightBuilder.Field("name")); // 高亮字段 // 添加高亮查询条件到搜索源 searchSourceBuilder.highlighter(highlightBuilder); // *********************** // 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段 searchSourceBuilder.fetchSource(new String[]{"name","address","timestamp"},new String[]{}); // 向搜索请求对象中设置搜索源 searchRequest.source(searchSourceBuilder); // 执行搜索,向ES发起http请求 SearchResponse searchResponse = client.search(searchRequest); // 搜索结果 SearchHits hits = searchResponse.getHits(); // 匹配到的总记录数 long totalHits = hits.getTotalHits(); // 得到匹配度高的文档 SearchHit[] searchHits = hits.getHits(); // 日期格式化对象 soutData(searchHits); }

根据查询结果的数据结构来获取高亮的数据,替换原有的数据:

private void soutData(SearchHit[] searchHits) throws ParseException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (SearchHit hit : searchHits) { // 文档的主键 String id = hit.getId(); // 源文档内容 Map<String, Object> sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name"); // 获取高亮查询的内容。如果存在,则替换原来的name Map<String, HighlightField> highlightFields = hit.getHighlightFields(); if( highlightFields != null ){ HighlightField nameField = highlightFields.get("name"); if(nameField!=null){ Text[] fragments = nameField.getFragments(); StringBuffer stringBuffer = new StringBuffer(); for (Text str : fragments) { stringBuffer.append(str.string()); } name = stringBuffer.toString(); } } String type= (String) sourceAsMap.get("type"); // 日期 Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); } }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #es #JAVA #查询 #pom依赖12 #yml配置13 #创建索引14 #创建映射15