一、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依赖1.2 yml配置org.elasticsearch.client elasticsearch-rest-high-level-client7.9.1 org.elasticsearch elasticsearch7.9.1
spring: elasticsearch: rest: uris: 127.0.0.1:9200 read-timeout: 60s1.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(); // 源文档内容 Map2.2 精准匹配sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name"); // 日期 Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); } }
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开发框架").minimumShouldMatch("70%"));
注:“spring开发框架”会被分为三个词:spring、开发、框架
设置"minimum_should_match": "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向下取整得2,表示至少有两个词在文档中要匹配成功。
MultiQuery可以通过 fields 属性来设置多个域联合查找。
DSL:
{ "query": { "multi_match": { "query": "Spring开发", "minimum_should_match": "70%", "fields": ["name", "description"] } } }
java api:
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("Spring开发框架", "name", "address").minimumShouldMatch("70%"));
提升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(""); // 高亮前缀 highlightBuilder.postTags(""); // 高亮后缀 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(); // 源文档内容 MapsourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name"); // 获取高亮查询的内容。如果存在,则替换原来的name Map 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); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)