背景:
最近做了一个App需要使用的搜索建议的功能,效果就是我们再使用百度搜索的时候:
可以看到,每输入一个字符就会发送一个请求;
这个功能看似很高大上,其实做一个简单的实现还是很简单的。
原理:
这个技术,主要有以下的技术点:
- Elasticsearch7.4.1(以下称为ES)推荐
- ik中文分词插件
首先需要将数据存放到ES中,当然存放的时候需要做一些简单的处理,需要将搜索的field做分词放在列表中,存入到ES之中。由于数据爬取是采用的Python,所以在这里贴Python代码,数据采集是使用的JD的商品数据
//由传过来的字符生成suggest的数组
def gen_suggest(index, info_tuple):
# 由字符串生成建议
used_word = set()
suggest = []
for text, wight in info_tuple:
if text:
words = es.indices.analyze(index="jd_product", body={
"analyzer":"ik_max_word", "text": "{0}".format(text)})
analyzed_word = set([r["token"] for r in words["tokens"] if len(r["token"])>1])
print(analyzed_word)
naw_words = analyzed_word - used_word
else:
naw_words = set()
if naw_words:
suggest.append({
"input": list(naw_words),"weight":wight})
print(suggest)
return suggest
def save_ES(result):
jd = JD_Product()
jd.by_self = result["by-self"]
jd.comment_cnt = result["comment-cnt"]
jd.title = result["title"]
jd.pid = result["pid"]
jd.image_data_lazy_img = result["image-data-lazy-img"]
jd.image_src = result["image-src"]
jd.price = result["price"]
jd.shop_name = result["shop-name"]
# 生成建议的数据
jd.suggest = gen_suggest(JD_Product, ((jd.title, 10), (jd.shop_name, 7)))
jd.save()
此时存放在ES中的数据是这样的:
{
"_index": "jd_product",
"_type": "_doc",
"_id": "opSOOXEBy66jXuB0CIVc",
"_version": 1,
"_seq_no": 15536,
"_primary_term": 1,
"found": true,
"_source"