知了目前使用的是ES为Java提供一个查询接口,叫做QueryBuilder
当用户传入查询后,现在我们做了一个这个事情——多字段匹配查询
reBuilder = reBuilder.must(multiMatchQuery(query, "title", "text"));
其中这个query就是用户的输入
官方文档给出的解释是:Finds documents which match any field, but uses the _score from the best field.
实际上这个多字段匹配查询可以这么理解:
比如说用户搜索一个「北京邮电大学」
我在标题和正文里分别对北京邮电大学进行全文检索,然后分别在两个字段里按照命中率(或者说_score)进行排序
然后将这两个排序结果取并集,在两个字段命中率都高的排名考前
最后得到一个没有重复的文档集合,返回给用户
这就造成一个问题,通过这种方法获得的结果是这样的
["0": { "id": 17516, "crop_id": null, "user_id": 23, "create_time": 1631950049000, "edit_time": 1631950049000, "title": "计算机学院2021级培养方案", "text": "是一个一个数组的形式,没有命中率,也不知道是在标题还是正文还是附件搜出来的 2.或许可以采用的解决方法计算机学院2021级培养方案,包括:
北京邮电大学专业学位硕士研究生培养方案(2021级)-9.14.pdf
", "attachment": null, "superior": 0, "recognition": null, "opposition": null, "pageview": null, "collection": null, "group_id": "", "label_id": "111,203,129", "user_name": null, "group_name": null, "label_name": null, "permissionid": "0" }]
北京邮电大学博士研究 生培养方案(2021级)-9.3.pdf
北京邮电大学学术学位硕士研究生培养方案(2021级)-9.9.pdf
北京邮电大学直博研究生培养方案(2021级)-9.3.pdf
自行封装一个查询函数,来实现一个类似于多字段查询的功能
主要原理还是调用ES的最原生的Restful API分别查询各个字段,再按照我们的规则进行合并,例如
POST http://192.168.36.136:9200/_search
{ "query": { "query_string": { "query": "北京邮电大学" } } }
可以得到这样的返回
{ "took": 246, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 105, "max_score": 15.921347, "hits": [ { "_index": "knowledge_ms", "_type": "resource", "_id": "17516", "_score": 15.921347, # 这里能得到一个命中率 "_source": { "id": 17516, "crop_id": null, "user_id": 23, "create_time": 1631950049000, "edit_time": 1631950049000, "title": "计算机学院2021级培养方案", "text": "计算机学院2021级培养方案,包括:
北京邮电大学专业学位硕士研究生培养方案(2021级)-9.14.pdf
", "attachment": null,
北 京邮电大学博士研究生培养方案(2021级)-9.3.pdf
北京邮电大学学术学位硕士研究生培养方案(2021级)-9.9.pdf
北京邮电大学直博研究生培养方案(2021级)-9.3.pdf
按照这样的规则我们能分别得到标题命中率的排名、正文命中率的排名和附件命中率的排名
然后我们可以对这三个排名拉一个(可能有重复文档的)大排名给用户展示出来,并且告诉用户是哪里搜出来的
最后得到的感觉大概是这个样子
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)