ElasticSearch High Level REST API【2】搜索查询

2023-11-08

如下为一段带有分页的简单搜索查询示例

在search搜索中大部分的搜索条件添加都可通过设置SearchSourceBuilder来实现,然后将SearchSourceBuilder

RestHighLevelClient client = ElasticClient.getRestHighLevelClient();
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
sourceBuilder.from(0);
sourceBuilder.size(5);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //设置一个可选的超时,控制允许搜索的时间
searchRequest.source(sourceBuilder);

try {
    SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
    Long total = search.getHits().getTotalHits(); //获取匹配的总数量
    System.out.println("总记录数:" + total);
    for (SearchHit hit : search.getHits().getHits()) {
              float score = hit.getScore(); //获得分数,即匹配度 
          String source = hit.getSourceAsString();
          System.out.println(source);
    }

} catch (IOException e) {
    e.printStackTrace();
}

search查询的返回值为SearchResponse,调用SearchResponse的getHits()方法会获取SearchHits对象,然后再通过SearchHits的getHits()方法即返回一个SearchHit[]数组。

遍历SearchHit[]数组获取每一个对象,通过hit.getScore()可获取分数,即搜索匹配度。通过hit.getSourceAsString()可得到对象的json字符串。

备注:在上述查询中用到了termQuery查询,ES还提供了matchQuery查询,不同的查询需求中需要选择不同的查询,在此需要了解这两个查询的区别:

  • termQuery : term为不使用分词器查找,类似精确查找。
  • matchQuery : mactch为使用分词器进行查找,会查询到一些近似匹配的内容。

SearchHit使用汇总

要获取返回的内容,需要获得SearchHit,下面总结下SearchHit的一些使用:

SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits(); //查询命中总数
float maxScore = hits.getMaxScore(); //查询命中的最高分数
//嵌套在SearchHits可以迭代获取单个搜索结果中
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
    //使用SearchHit做一些事情
}
//通过SearchHit还可以获取 返回数据 的索引、类型、docId和得分等基本信息
String index = hit.getIndex(); 
String type = hit.getType();
String id = hit.getId();
float score = hit.getScore();
//hit还可以以Json字符串或Map的形式返回数据
String sourceAsString = hit.getSourceAsString();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String documentTitle = (String) sourceAsMap.get("title");
List<Object> users = (List<Object>) sourceAsMap.get("user");
Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");

指定排序

sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //按分数(即匹配度)排序
sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC)); //通过指定字段来排序

排序有两种排序方式,第一通过ScoreSortBuilder实现按分数(即匹配度)排序

第二种方式通过指定字段来排序,如上图所示通过“_uid”字段排序

关闭检索

有时候我们只想要知道到底匹配了多少条具体,但不关系具体每条记录的内容,这个时候我们可以选择关闭检索,不去查询每天数据的内容,可通过如下方式实现:

sourceBuilder.fetchSource(false);

关闭检索后,运行程序输出如下

只返回了总记录数,遍历输出每条数据均为 null

另外还可以通过sourceBuilder接受一个或多个数组,来控制要要返回哪些字段,排除哪些字段。具体实现如下,第一个数组参数为要接受的字段,第二个数组参数为要排除的内容:

String[] includeFields = new String[] {"title", "user", "innerObject.*"};
String[] excludeFields = new String[] {"_type"};
sourceBuilder.fetchSource(includeFields, excludeFields);

高亮显示

通过向SearchSourceBuilder添加HighlightBuilder示例可添加高亮显示功能

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder(); 
HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title"); 
highlightTitle.highlighterType("unified"); //字段高亮显示类型,默认用标签包裹高亮字词
highlightBuilder.field(highlightTitle);
searchSourceBuilder.highlighter(highlightBuilder);

以上只是在查询中加入高亮显示的功能,那么我们如何在查询结果中获取呢,通过SearchHit的getHighlightFields()方法获取我们需要关键内容:

SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits.getHits()) {
    Map highlightFields = hit.getHighlightFields();
    HighlightField highlight = highlightFields.get("title"); 
    Text[] fragments = highlight.fragments();  
    String fragmentString = fragments[0].string();
}

 聚合操作

public void aggregation(){
       RestHighLevelClient client = elasticClient.getRestHighLevelClient();
       SearchRequest searchRequest = new SearchRequest();
       SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
       TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_sex")
               .field("sex.keyword");   //若不加keyword,在text类型上进行聚合操作时会报错
       aggregation.subAggregation(AggregationBuilders.avg("avg_age")
               .field("age"));  //avg_age 为子聚合名称,名称可随意
       searchSourceBuilder.aggregation(aggregation);
       searchRequest.source(searchSourceBuilder);
       SearchResponse searchResponse = null;
       try {
           searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
       } catch (IOException e) {
           e.printStackTrace();
       }
       Aggregations aggregations = searchResponse.getAggregations();
       Terms byCompanyAggregation = aggregations.get("by_sex");
       Terms.Bucket elasticBucket = byCompanyAggregation.getBucketByKey("女性");
       Avg averageAge = elasticBucket.getAggregations().get("avg_age");
       double avg = averageAge.getValue();
       System.out.println("女性平均年龄:"+avg);
}

 

转载于:https://www.cnblogs.com/chentop/p/10296501.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ElasticSearch High Level REST API【2】搜索查询 的相关文章

  • Android 接收外语(例如俄语)Json

    伙计们 美好的一天 我正在尝试接收一些JSON它是用俄语写的 可能也必须以中文接收 主要是在全球范围内 所以我必须收到的任何语言信件JSON 问题是当我收到JSON应该看起来像 file path storage paqstorage pa
  • 具有 ISO 日期格式的 WCF REST JSON

    我在 WCF Web 服务 框架 4 0 中使用 JSON 支持 ISO 日期格式时遇到了一个大问题 我尝试了很多 但还没有运气 休息服务 WebInvoke Method PUT UriTemplate mvnoid OrderID Re
  • 将数据从 Django 传递到 D3

    我正在尝试使用 Django 和 D3 js 编写一个非常基本的条形图 我有一个名为 play 的对象 其中包含一个名为 date 的日期时间字段 我想要做的是显示一段时间内按月分组的播放次数 基本上我有两个问题 如何将这些内容按月分组并统
  • 如何在Python中检查神秘的反序列化对象

    我正在尝试将 JSON 加载回对象中 loads 方法似乎工作正常 但该对象似乎没有我期望的属性 我怎样才能检查 检查我拥有的对象 这是基于网络的代码 results Subscriber firstname Neal lastname W
  • 用于生成和使用 JSON 的控制器的 Spring RequestMapping

    具有多个消费和生产的 Spring 控制器application json 我的代码充满了长注释 例如 RequestMapping value foo method RequestMethod POST consumes MediaTyp
  • Pandas DataFrame 到嵌套 JSON 而不更改数据结构

    I have pandas DataFrame import pandas as pd import json df pd DataFrame 2016 04 30T20 02 25 693Z vmPowerOn vmName 2016 0
  • 从Lua到C的Lua嵌套表

    我不幸未能将嵌套 Lua 表转换为 C json 对象 我正在使用 LuaTableToJson 请参阅后面的代码 其中 index 是要检索的参数索引 PopOneArg 是根据值的类型处理值的例程 当有嵌套表时 我想递归地调用 LuaT
  • UnicodeDecodeError:“utf8”编解码器无法解码位置 0 中的字节 0xa5:起始字节无效

    我在用Python 2 6 CGI脚本但在执行时在服务器日志中发现此错误json dumps Traceback most recent call last File etc mongodb server cgi bin getstats
  • 调试测试时从 local.setting.json 读取值

    在运行或调试测试时 我似乎无法从天蓝色函数中的该文件中读取任何内容 但是在本地调试整个应用程序时它工作得很好 任何人都可以解释为什么吗 IsEncrypted false Values xyz 123 var res Configurati
  • 在 postgresql 中,如何在 jsonb 键上返回布尔值而不是字符串?

    在下面的查询中 isComplete 和 isValid 以字符串形式返回 但是 它们被保存为布尔值 如何获取要返回的这些字段的布尔表示形式 query SELECT data gt gt id AS id data gt gt name
  • POST JSON 对象到 aws lambda

    如何通过 aws API 网关将 json 对象发布到 aws lambda 函数 p s 我的目标是用 python 编写 lambda 函数 然后将其发布到 aws SQS 提前致谢 我想到了 现在 我有一个 API 网关接受客户端发布
  • 准确的JSON文本编码检测

    RFC4627 中描述了一种在 BOM 不存在时识别 Unicode 编码的方法 这依赖于 JSON 文本中的前 2 个字符始终是 ASCII 字符 但在RFC7159中 规范将JSON文本定义为 ws value ws 意味着单个字符串值
  • 如何在flutter中使用API​​调用嵌套的json数据?

    我的 JSON 看起来像这样 Info c type id 1 cleaning type A Cleaning c type id 2 cleaning type B Cleaning c type id 3 cleaning type
  • 使用具有不同参数的 Jackson for List 将 JSON 映射到 pojo

    JSON 格式 0 cast showname woh pagle type Episodes video src video mp4 DRM False 这里的问题是我遇到以下异常 org codehaus jackson map Jso
  • 使用 json 模式强制对象非空

    我们可以强制类型对象的空属性如下 description voice mail record type object additionalProperties false properties 正如所解释的here https stacko
  • 如何使用 CloudFormation 覆盖容器环境变量来运行 AWS ECS 任务

    我正在寻找一种运行 ecs 任务的方法 我已经有了集群和任务定义设置 我只是想使用 CloudFormation 模板触发任务 我知道我可以通过单击控制台来运行任务并且它工作正常 对于 cfn 需要正确定义方法 检查所附的屏幕截图 我想使用
  • " 是 JSON 字符串

    我有一个 JSON 字符串 当使用 Model JsonData 在 ASP NET MVC 页面中显示时 它看起来像这样 id 123 text Consumer parent 当我在 JavaScript 代码中使用相同的 Model
  • Mysql - 如何比较两个 Json 对象?

    将整个 MySql json 列与 json 对象进行比较的语法是什么 以下不起作用 select count criteria from my alerts where criteria industries 1 locations 1
  • 加密json数据

    如何加密从客户端到服务器来回传输的 JSON 数据 当我使用firebug时 我可以看到所有数据 内容在result d 我正在使用 ASP NET 3 5 和 C 我们的管理员已将网站设置为使用 https 但我仍然可以发送 POST 请
  • 保存 dat.gui 预设以动态添加控件?

    我正在向 dat gui 界面动态添加控件 但 保存设置 功能无法识别它们 var mygui new dat GUI mygui remember mygui standard way of adding a control mygui

随机推荐