es 中文前缀短语匹配(搜索智能补全) prefix查询和completion suggester两种方式

需求:es进行前缀匹配,用来进行智能补全
方式一:正常索引库类型,字段类型为text
过程:es正常的prefix只能进行词语匹配,而中文的分词大部分按字分词,不按语义分词,所以无法搜索出正确的前缀匹配,而能进行短语匹配的match_phrase_prefix匹配,是正常按前几个词进行匹配,最后一个词进行前缀匹配,也不满足要求。查阅很多资料发现,离正确答案只差一个keyword
代码

curl -X POST "localhost:9200/information_completion/_search?pretty" -H 'Content-Type:application/json' -d '{
  "_source": ["text"],
  "text": {
    "prefix": {
      "text.keyword": "中云街"
    }
  }
}
'

参考资料


以上方式存在的问题是:无法计算得分,前缀匹配到的所有记录的得分,也就是score,是一致的,那么引入方式二,重新建库。


方式二:使用completion suggester建议器建库
流程:使用以下代码建立索引,建出来字段类型为completion,然后用建议器的方式进行前缀搜索匹配,可以通过建库时自定义权重的方式,使得搜索的结果得分不一致,并且使得自己所需要的热词权重较高。

建库curl代码

curl -X PUT "localhost:9200/info_completion" -H 'Content-Type: application/json' -d '
{
    "mappings" : {
      "properties" : {
        "id" : {
          "type" : "text"
        },
        "query" : {
          "type" : "completion",
          "analyzer" : "ik_max_word"
        },
        "text" : {
          "type" : "text",
          "analyzer" : "ik_max_word",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
}
'

(需要注意的是,如果字段类型为completion,就无法正常使用term query以及match等方式来查询了,如果两者都需要支持,需要再加一个text字段来保存)。

建库脚本

file_path = "/home/xxx/xxx.txt"
with open(file_path, 'r', encoding="utf-8") as f:
    lines = f.readlines()

i = 0
for line in lines:
    data = line.split()
    d = {"id": data[0], "query": data[1]}
    # print(json_str)
    es.index(index="information_completion", id=i, body=d)
    i += 1
es.indices.refresh(index="information_completion")

print("finish")

查询curl代码

curl -X POST "localhost:9200/info_completion/_search?pretty" -H 'Content-Type:application/json' -d '
{
  "suggest": {
    "info_suggest": {
      "prefix": "农业银行",
      "completion": {
        "field": "query",
        "size": "10"
      }
    }
  }
}
'

查询脚本片段

def get_prefix_res(query, size):
    res = []
    start = 0
    query_body = {
        "suggest": {
            "info_suggest": {
                "prefix": query,
                "completion": {
                    "field": "query",
                    "size": size
                }
            }
        }
    }
    data = es.search(index="information_completion", body=query_body)
    print("get_prefix: ")
    suggest = data['suggest']['info_suggest'][0]["options"]
    for i in range(0, min(10, len(suggest))):
        d = {"score": suggest[i]["_score"], "content": suggest[i]["_source"]["query"]}
        print(d)
        res.append(d)
    if len(suggest) == 0:
        return res
    max_val = suggest[0]["_score"]
    min_val = suggest[len(suggest) - 1]["_score"]
    for item in res:
        item["score"] = cal_val(item.get("score"), max_val, min_val)
    print(res)
    print(max_val, ' ', min_val, ' ', len(suggest))
    return res

参考资料
https://zhuanlan.zhihu.com/p/666534606
https://www.cnblogs.com/Neeo/articles/10695019.html

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Completion Suggester是一种用于关键词前缀匹配的功能,它可以根据用户输入的前缀来提供相关的补全选项。根据引用\[1\]的描述,Completion Suggester在精准程度上比Phrase和Term要好,但在召回率上则相对较低。因此,如果业务需求可以满足,只使用Completion Suggester进行前缀匹配是最理想的选择。然而,使用Completion Suggester并不是一件容易的事情,需要根据数据特性和业务需求,灵活搭配analyzer和mapping参数,并进行反复调试,才能获得理想的补全效果。此外,还可以使用Fuzzy Queries来增加匹配的模糊程度。总之,使用Completion Suggester需要根据具体情况进行调整和优化,以获得最佳的模糊匹配效果。 #### 引用[.reference_title] - *1* *2* [Elasticsearch Suggester详解(自动补全)](https://blog.csdn.net/qq_40374604/article/details/114841800)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ElasticSearch suggester](https://blog.csdn.net/zhanglh046/article/details/78536021)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值