如何从Elasticsearch非精确搜索结果中移除精确搜索的PK匹配项?
实现思路:从非精确搜索结果中排除精确搜索匹配的PK项
方案1:客户端二次过滤(简单易实现)
- 先执行精确搜索,提取所有结果中的
pk字段值,整理成一个集合(比如{"USER#1"}) - 执行非精确搜索,拿到结果后在客户端过滤掉所有
pk属于该集合的文档
示例Python代码:
# 1. 执行精确搜索,获取要排除的PK列表 exact_search_response = es.search( index="your_index", query={"term": {"input": "dev"}} ) excluded_pks = {hit["_source"]["pk"] for hit in exact_search_response["hits"]["hits"]} # 2. 执行非精确搜索并过滤结果 fuzzy_search_response = es.search( index="your_index", query={"match": {"input": "dev"}} ) filtered_hits = [hit for hit in fuzzy_search_response["hits"]["hits"] if hit["_source"]["pk"] not in excluded_pks]
方案2:Elasticsearch端一次查询完成(高效,减少数据传输)
利用bool查询组合非精确搜索条件与排除规则,直接在ES层面过滤目标PK:
- 先执行精确搜索拿到PK列表(同方案1第一步)
- 在非精确搜索的查询中添加
must_not子句,用terms匹配要排除的PK值
示例查询DSL:
{ "query": { "bool": { "must": [ // 非精确搜索条件,比如模糊匹配input字段 {"match": {"input": "dev"}} ], "must_not": [ // 排除精确搜索得到的PK值 {"terms": {"pk": ["USER#1"]}} ] } } }
若需避免两次查询,可尝试基于临时索引的子查询,但复杂度较高,仅推荐数据量极大的场景使用。
方案3:脚本字段过滤(灵活但性能稍低)
通过script查询动态判断文档pk是否在排除列表中,适合特殊业务场景:
示例查询DSL:
{ "query": { "bool": { "must": [{"match": {"input": "dev"}}], "must_not": [ { "script": { "script": { "source": "params.excluded_pks.contains(doc['pk'].value)", "params": { "excluded_pks": ["USER#1"] } } } } ] } } }
内容的提问来源于stack exchange,提问作者luickx
相关产品推荐
相关产品推荐

