Elasticsearch 的自动补全以及RestAPI的使用

Elasticsearch 提供了强大的自动补全 (Autocomplete) 功能,以下为一个基础的自动补全DSL语句

bash 复制代码
{
  "suggest": {
    "my_suggestion": {  // 自定义建议器名称,可按需修改
      "text": "ap",     // 用户输入的前缀(如搜索框输入的字符)
      "completion": {
        "field": "title_completion",  // 必须是 mapping 中定义的 completion 类型字段
        "size": 5,                    // 返回最多 5 条补全结果
        "skip_duplicates": true       // 跳过重复结果
      }
    }
  }
}
字段名 作用 注意事项
suggest 固定顶层字段,所有建议查询(包括自动补全)都必须嵌套在该字段下 必选
my_suggestion 自定义建议器名称,用于区分不同的补全逻辑(可随意命名) 必选,需保证语义清晰
text 用户输入的前缀(如搜索框实时输入的字符,ES 会用它匹配补全结果) 必选,需与业务场景的输入对应
completion 固定类型,指定使用 Elasticsearch 「Completion Suggester」实现补全 必选
field 索引中定义的 completion 类型字段(需提前在 mapping 中配置) 必选,字段类型必须正确
size 控制返回的补全结果数量(如设置为 10 则最多返回 10 条) 可选,默认 5
skip_duplicates 是否跳过重复结果(true 则去重,false 保留重复) 可选,默认 false

带上下文过滤器的DSL语句,如果你的补全需要区分类别 / 场景 (如「手机」和「电脑」分类下的不同补全),可以用 contexts 过滤:

bash 复制代码
{
  "suggest": {
    "my_suggestion": {
      "text": "ip",
      "completion": {
        "field": "title_completion",
        "size": 5,
        "contexts": {  // 上下文过滤规则
          "category": [  // 假设 mapping 中定义了 category 上下文
            {
              "context": "electronics",  // 只返回「电子产品」分类的补全
              "boost": 2  // 结果权重 +2(可选,用于调整优先级)
            }
          ]
        }
      }
    }
  }
}
字段名 作用 依赖条件
contexts 按「上下文」过滤补全结果(如分类、地区等) mapping 需提前定义 context
category 自定义的上下文名称(需与 mapping 中配置一致) 必选(与 mapping 对应)
context 具体的上下文值(如 "electronics" 表示「电子产品」分类) 必选
boost 给该上下文结果增加权重(影响排序,数值越大越靠前) 可选,默认 1

如果用户输入可能有拼写错误,可以开启 fuzzy

bash 复制代码
{
  "suggest": {
    "my_suggestion": {
      "text": "aple",  // 故意模拟拼写错误
      "completion": {
        "field": "title_completion",
        "fuzzy": {      // 开启模糊匹配
          "fuzziness": 1  // 允许 1 次编辑距离(如增/删/改 1 个字符)
        }
      }
    }
  }
}
字段名 作用 场景
fuzzy 开启模糊匹配,允许用户输入有拼写错误时仍能匹配结果 搜索框输入容错
fuzziness 允许的最大编辑距离(0 严格匹配,1 允许 1 处错误,AUTO 自动适配) 必选(开启模糊时)

以下为在java代码当中运用的实例

java 复制代码
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.elasticsearch.search.builder.SearchSourceBuilder;
​
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
​
public class SimpleESAutocomplete {
    public static void main(String[] args) {
        // 构建 ES 客户端,连接本地 9200 端口
        try (RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")))) {
​
            // 执行最简自动补全查询,参数:客户端、索引名、补全字段、用户输入前缀
            List<String> results = basicCompletionSuggest(client, "users", "name_suggest", "mic");
            System.out.println("自动补全结果: " + results);
​
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    /**
     * 最简自动补全方法:仅用 Completion Suggester 实现基础补全
     * 流程拆分:1.准备Request  2.准备DSL  3.发起请求  4.解析结果
     * @param client   ES 客户端
     * @param index    索引名称
     * @param field    补全字段(需是 mapping 中配置的 completion 类型)
     * @param prefix   用户输入的前缀关键字
     * @return 补全建议结果列表
     * @throws IOException 网络或 ES 操作异常
     */
    private static List<String> basicCompletionSuggest(RestHighLevelClient client, 
                                                       String index, 
                                                       String field, 
                                                       String prefix) throws IOException {
        
        // 1. 准备 Request(初始化搜索请求 & 绑定索引)
        SearchRequest searchRequest = new SearchRequest(index); 
​
        // 2. 准备 DSL(构建补全相关的查询逻辑,设置到 SearchSourceBuilder 中)
        // 2.1 构建补全建议器
        CompletionSuggestionBuilder suggestionBuilder = SuggestBuilders.completionSuggestion(field)
                .prefix(prefix)  // 设置用户输入的前缀
                .size(5);        // 最多返回 5 条补全结果(可按需调整)
        // 2.2 组装建议查询
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("simple_suggest", suggestionBuilder); 
        // 2.3 把建议查询放入搜索源
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.suggest(suggestBuilder); 
        // 2.4 将构建好的 DSL 关联到 Request
        searchRequest.source(sourceBuilder); 
​
        // 3. 发起请求(调用客户端的 search 方法执行查询)
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); 
​
        // 4. 解析结果(从响应中提取补全建议并封装成 List 返回)
        List<String> results = new ArrayList<>();
        Suggest suggest = response.getSuggest();
        if (suggest != null) {
            //根据补全查询名称,获取补全结果
            CompletionSuggestion completionSuggestion = suggest.getSuggestion("simple_suggest");
            //获取option里面就是我们要传回的数据
            completionSuggestion.getOptions().forEach(option -> 
                    results.add(option.getText().string()));
        }
        return results;
    }
}

自动补全对字段也是有要求的,比方说类型应该是completion,字段值是多词条的数组以便于分词。、

关键步骤:

  1. 准备 Request :创建SearchRequest并指定索引。

  2. 准备 DSL:

    • 使用CompletionSuggestionBuilder构建补全查询,设置前缀和返回数量。

    • 将补全查询添加到SearchSourceBuilder中。

  3. 发起请求:执行查询并获取响应。

  4. 解析结果 :从响应中提取补全建议文本,存入List返回。

注意事项:

  1. 数据准备

    • 必须先在 ES 中创建索引并定义completion类型字段。

    • 向索引中写入文档时,需填充补全字段。

  2. 映射限制

    • completion类型字段不支持分词,仅支持精确前缀匹配。

    • 如需分词后的前缀匹配,可使用search_as_you_type类型。

  3. 部署要求

    • 本地需运行 Elasticsearch 服务(默认 9200 端口)。

    • 依赖 ES Java 客户端(Maven/Gradle 引入)。

相关推荐
楽码3 分钟前
安装和编写grpc协议文件
服务器·后端·grpc
码农之王5 分钟前
(二)TypeScript前置编译配置
前端·后端·typescript
九转苍翎8 分钟前
Java SE(13)——工具类
java·工具类
小马爱打代码12 分钟前
数据结构 - Java 队列
java·数据结构
一眼万年0413 分钟前
Kafka LogManager 深度解析
后端·kafka
天行健的回响15 分钟前
一次多线程改造实践:基于ExecutorService + CompletionService的并发处理优化
后端
厚衣服_331 分钟前
第18篇:数据库中间件架构中的服务治理与限流熔断机制设计
数据库·中间件·架构
盖世英雄酱5813638 分钟前
🚀不改SQL,也能让SQL的执行效率提升100倍
java·数据库·后端
陈随易1 小时前
Bun v1.2.16发布,内存优化,兼容提升,体验增强
前端·后端·程序员
GetcharZp1 小时前
「Golang黑科技」RobotGo自动化神器,鼠标键盘控制、屏幕截图、全局监听全解析!
后端·go