[请教] es 搜索建议的使用实现搜索补全

2023-05-10 10:13:51 +08:00
 jiobanma

背景

mysql 的业务表中有 student 表和 class 表,其中 student 表中有 studentCode ,studentName 等.class 表中有 classCode ,className 等。想要实现一个功能:前端有一个输入框,根据用户输入的内容进行联想,匹配优先级为:studentCode ,studentName ,classCode ,className 。前缀匹配就好。

问题

最开始考虑到的是使用 es 的搜索建议功能。对 es 的使用较少,怕走弯路,想请教下 v2 的大佬们,给点指点建议。

  1. 如果我把库里所有的数据同步到 es 里。索引的结构为类似为
{"field":"studentCode","value":"SN0001"},{"field":"studentName","value":"张三"},{"field":"classCode","value":"C0001"},{"field":"className","value":"韭菜班"}

这样处理是最简单的感觉。直接给 value 字段加上搜索建议,但是不知道这个怎么定优先级。不知道能实现按照指定的优先级来查询吗?还有感觉这中索引结构有些不优雅。 2. 可以通过下面这种结构实现吗?

    {
        "studentCode":"SN001",
        "studentName":"张三",
        "classCode":"C001",
        "className":"韭菜班"
    },
    {
        "studentCode":"SN001",
        "studentName":"张三",
        "classCode":"C001",
        "className":"韭菜班"
    }
  1. 或者还有其他好一点的方案吗?
1188 次点击
所在节点    程序员
4 条回复
foxthree
2023-05-10 10:21:54 +08:00
用 es 的 function_score 来对每个字段的搜索匹配加权应该可以吧
CaptainD
2023-05-10 10:51:53 +08:00
多字段查询 + boost 加权应该可以满足要求,boost 权重需要慢慢调整,索引结构要注意下,字段类型、是否分词、中英文分词器等
sadfQED2
2023-05-10 11:09:28 +08:00
方案 1 用自定义函数打分,DSL:
```
{
"from": 0,
"size": 20,
"_source": true,
"min_score": 0.001,
"sort": [
{
"_score": "desc"
}
],
"query": {
"function_score": {
"query": {
"bool": {
"should": [ ],
"filter": [],
"must": [
{
"bool": {
"should": [
{
"prefix": {
"field": {
"query": "张三"
}
}
}
]
}
}
],
"must_not": [ ]
}
},
"boost_mode": "replace",
"script_score": {
"script": {
"params": {},
"source": """
if(_score == 0){return 0;}
String type = (String)doc['field'].value;
if(type == "studentCode") return _score + 40000;
if(type == "studentName") return _score + 30000;
if(type == "classCode") return _score + 20000;
if(type == "className") return _score + 10000;
"""
}
}
}
}
}

```


方案 2 用 boost 加权,DSL:

```
{
"from": 0,
"size": 20,
"_source": true,
"sort": [
{
"_score": "desc"
}
],
"query": {
"bool": {
"should": [ ],
"filter": [],
"must": [
{
"bool": {
"should": [
{
"prefix": {
"studentCode": {
"query": "张三",
"boost": 4
}
}
},
{
"prefix": {
"studentName": {
"query": "张三",
"boost": 3
}
}
},
{
"prefix": {
"classCode": {
"query": "张三",
"boost": 2
}
}
},{
"prefix": {
"className": {
"query": "张三",
"boost": 1
}
}
}
]
}
}
],
"must_not": [ ]
}
}
}
```

盲写的 DSL 可能有点小问题,你测试下
deadlyn
2023-05-10 13:23:22 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/938796

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX