当前位置:首页 > 技术 > 正文内容

Elasticsearch Java客户端常用查询操作详解

访客 技术 2026年7月26日 1

初始化测试数据

首先通过Bulk API批量插入人物数据到sanguo索引的dahan类型中,用于后续查询演示:

curl -X POST "http://hadoop01:9200/sanguo/dahan/_bulk" -H "Content-Type: application/json" -d '
{ "index": {} }
{"studentNo":1,"name":"刘备","gender":"男","age":24,"birthday":"1985-02-03","classNo":1,"address":"湖南省长沙市","isLeader":true}
{ "index": {} }
{"studentNo":2,"name":"关羽","gender":"男","age":22,"birthday":"1987-08-23","classNo":2,"address":"四川省成都市","isLeader":false}
{ "index": {} }
{"studentNo":3,"name":"糜夫人","gender":"女","age":19,"birthday":"1990-06-12","classNo":1,"address":"上海市","isLeader":false}
{ "index": {} }
{"studentNo":4,"name":"张飞","gender":"男","age":20,"birthday":"1989-07-30","classNo":3,"address":"北京市","isLeader":false}
{ "index": {} }
{"studentNo":5,"name":"诸葛亮","gender":"男","age":18,"birthday":"1992-04-27","classNo":2,"address":"江苏省南京市","isLeader":true}
{ "index": {} }
{"studentNo":6,"name":"孙尚香","gender":"女","age":16,"birthday":"1994-05-21","classNo":3,"address":"广东省深圳市","isLeader":false}
{ "index": {} }
{"studentNo":7,"name":"马超","gender":"男","age":19,"birthday":"1991-10-20","classNo":1,"address":"黑龙江省哈尔滨市","isLeader":false}
{ "index": {} }
{"studentNo":8,"name":"赵云","gender":"男","age":23,"birthday":"1986-10-26","classNo":2,"address":"浙江省杭州市","isLeader":false}
'

1. 全文匹配查询(Match All)

使用matchAllQuery检索指定索引下的所有文档记录。

@Test
public void fetchAllDocuments() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.matchAllQuery())
        .get();

    SearchHits hits = response.getHits();
    System.out.println("总命中数:" + hits.getTotalHits());

    for (SearchHit hit : hits) {
        Map<String, Object> source = hit.getSource();
        System.out.println("姓名: " + source.get("name"));
        System.out.println("学号: " + source.get("studentNo"));
        System.out.println("性别: " + source.get("gender"));
        System.out.println("年龄: " + source.get("age"));
        System.out.println("地址: " + source.get("address"));
        System.out.println("班级: " + source.get("classNo"));
        System.out.println("-".repeat(40));
    }
}

2. 字符串解析查询(Query String)

基于Lucene语法对输入文本进行智能解析并执行多字段搜索。

@Test
public void queryStringSearch() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.queryStringQuery("孙尚香"))
        .get();

    handleSearchResults(response);
}

3. 通配符查询(Wildcard Query)

支持*匹配任意数量字符,?匹配单个字符。注意避免前导星号以防止性能问题。

@Test
public void wildcardAddressSearch() {
    // 查找地址以"广东"开头的记录
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.wildcardQuery("address", "广东*"))
        .get();

    handleSearchResults(response);
}

4. 精确词条查询(Term Query)

对未分词字段进行精确匹配,适用于关键字、枚举值等场景。

@Test
public void termMatchByName() {
    // 匹配多个名称中的任意一个
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.termsQuery("name", "刘备", "关羽", "张飞"))
        .get();

    handleSearchResults(response);
}

5. 字段全文检索(Match Query)

会对查询关键词自动分词,并根据字段映射使用的分析器处理后再匹配。

@Test
public void fullTextSearchByAddress() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.matchQuery("address", "上海"))
        .get();

    handleSearchResults(response);
}

6. 多字段联合检索(Multi Match)

在多个字段上同时执行相同的查询条件。

@Test
public void multiFieldSearch() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.multiMatchQuery("北京", "name", "address"))
        .get();

    handleSearchResults(response);
}

7. ID标识查询(IDs Query)

根据文档ID列表直接获取对应数据。

@Test
public void findByIds() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.idsQuery().addIds("AWNkQSCJzU0_wTuf7egi"))
        .get();

    handleSearchResults(response);
}

8. 模糊相似度查询(Fuzzy Query)

基于编辑距离算法查找拼写相近的内容。可用于容错搜索。

// 添加测试数据
// PUT /sanguo/dahan/123
{
  "name": "曹操",
  "gender": "男",
  "age": 40,
  "birthday": "1975-02-03",
  "classNo": 1,
  "address": "海淀区坐落于北京市",
  "isLeader": true
}

// PUT /sanguo/dahan/234
{
  "name": "董卓",
  "gender": "男",
  "age": 35,
  "birthday": "1975-02-03",
  "classNo": 1,
  "address": "北京it程序员",
  "isLeader": true
}

@Test
public void fuzzyTextSearch() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.fuzzyQuery("address", "北京市"))
        .get();

    for (SearchHit hit : response.getHits()) {
        System.out.println("相关性得分: " + hit.getScore());
        System.out.println("内容: " + hit.getSourceAsString());
    }
}

9. 数值与时间范围查询(Range Query)

筛选字段值落在特定区间的文档,支持数字、日期类型。

@Test
public void ageRangeFilter() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.rangeQuery("age")
            .from(18).to(22)
            .includeLower(true)
            .includeUpper(false))
        .get();

    handleSearchResults(response);
}

10. 布尔组合查询(Bool Query)

通过must、should、mustNot实现复杂逻辑组合查询。

// 新增示例数据
// PUT /sanguo/dahan/345
{
  "name": "貂蝉",
  "gender": "女",
  "age": 16,
  "birthday": "2000-02-03",
  "classNo": 1,
  "address": "北京市女it程序员",
  "isLeader": true
}

@Test
public void complexBooleanQuery() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.boolQuery()
            .must(QueryBuilders.matchQuery("address", "程序员"))
            .must(QueryBuilders.termQuery("gender", "女")))
        .get();

    handleSearchResults(response);
}

11. 结果排序(Sort Order)

按照指定字段升序或降序排列返回结果。

@Test
public void sortedResultByAge() {
    SearchResponse response = client.prepareSearch("sanguo")
        .setTypes("dahan")
        .setQuery(QueryBuilders.matchAllQuery())
        .addSort("age", SortOrder.ASC)
        .get();

    for (SearchHit hit : response.getHits()) {
        System.out.println("姓名: " + hit.getSource().get("name") +
                          ", 年龄: " + hit.getSource().get("age"));
    }
}

辅助方法

private void handleSearchResults(SearchResponse response) {
    SearchHits hits = response.getHits();
    System.out.println("匹配条目数:" + hits.getTotalHits());

    for (SearchHit hit : hits) {
        Map<String, Object> source = hit.getSource();
        System.out.println("→ 姓名:" + source.get("name") +
                          ", 学号:" + source.get("studentNo") +
                          ", 性别:" + source.get("gender") +
                          ", 年龄:" + source.get("age"));
        System.out.println("  地址:" + source.get("address") +
                          ", 班级:" + source.get("classNo"));
        System.out.println("  生日:" + source.get("birthday"));
        System.out.println("-".repeat(45));
    }
}
返回列表

上一篇:Java集合框架详解与应用实践

没有最新的文章了...

相关文章

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。