自动补全

自动补全 #

自动补全是在用户输入过程中,实时给出可能的搜索词建议。Easysearch 支持三种实现方式,各有适用场景:

方式时机性能适用场景
前缀匹配(match_phrase_prefix)查询时一般快速原型,无需特殊 mapping
Edge N-gram索引时大规模数据的前缀补全
Completion Suggester索引时最优高并发自动补全,支持权重控制

相关指南 #


前缀匹配(match_phrase_prefix) #

前缀匹配会在查询时,对最后一个 term 做前缀展开。典型做法是使用 match_phrase_prefixtext 字段上做查询。

不需要特殊 mapping,可以直接在现有 text 字段上使用。

GET shakespeare/_search
{
  "query": {
    "match_phrase_prefix": {
      "text_entry": {
        "query": "qui",
        "slop": 3
      }
    }
  }
}

参数说明 #

参数说明默认值
query查询文本必填
slop允许的词项位置偏移量0
max_expansions最后一个词项的最大前缀展开数量50
analyzer覆盖默认分析器字段默认分析器
zero_terms_query当分析器移除所有词项时的行为(noneallnone

性能注意:前缀匹配属于相对昂贵的查询。例如前缀为 a 时,可能会匹配到几十万 terms。建议通过 max_expansions 限制展开规模:

GET shakespeare/_search
{
  "query": {
    "match_phrase_prefix": {
      "text_entry": {
        "query": "qui",
        "slop": 3,
        "max_expansions": 10
      }
    }
  }
}

Edge N-gram 匹配 #

Edge N-gram 在索引时把单词切成一系列前缀片段,加速前缀查询。例如对 "quick" 做 edge N-gram:

前缀Token
1 字符q
2 字符qu
3 字符qui
4 字符quic
5 字符quick

配置分析器 #

定义带 edge_ngram 过滤器的自定义分析器:

PUT shakespeare
{
  "mappings": {
    "properties": {
      "text_entry": {
        "type": "text",
        "analyzer": "autocomplete",
        "search_analyzer": "standard"
      }
    }
  },
  "settings": {
    "analysis": {
      "filter": {
        "edge_ngram_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
        }
      },
      "analyzer": {
        "autocomplete": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "edge_ngram_filter"]
        }
      }
    }
  }
}

重要:建议在 mapping 中指定 search_analyzerstandard,避免查询词本身也被切成前缀导致过多无关匹配。这是少数需要"索引时分析器 ≠ 查询时分析器"的场景之一。

Edge N-gram 过滤器参数 #

参数说明默认值
min_gram最小前缀长度1
max_gram最大前缀长度2
preserve_original是否保留原始 tokenfalse

提示:除了 edge_ngram 过滤器,Easysearch 也支持 edge_ngram 分词器(tokenizer),它按字符级别切分而非基于词级别。过滤器在大多数自动补全场景中更实用。

测试分析器 #

POST shakespeare/_analyze
{
  "analyzer": "autocomplete",
  "text": "quick"
}

查询示例 #

GET shakespeare/_search
{
  "query": {
    "match": {
      "text_entry": {
        "query": "qui",
        "analyzer": "standard"
      }
    }
  }
}

Completion Suggester #

Completion Suggester 使用基于 FST(有限状态转换器) 的数据结构,常驻内存、专门优化前缀匹配性能,适合高并发自动补全场景。

创建 Mapping #

使用专门的 completion 字段类型:

PUT shakespeare
{
  "mappings": {
    "properties": {
      "text_entry": {
        "type": "completion"
      }
    }
  }
}

基础查询 #

GET shakespeare/_search
{
  "suggest": {
    "autocomplete": {
      "prefix": "To be",
      "completion": {
        "field": "text_entry",
        "size": 5
      }
    }
  }
}

Completion 参数 #

参数说明默认值
prefix前缀文本-
fieldcompletion 字段名必填
size返回建议数量5
skip_duplicates过滤重复建议false
fuzzy启用模糊补全(容错输入)不启用

模糊补全 #

支持容错输入的自动补全,用户打错字也能返回正确建议:

GET shakespeare/_search
{
  "suggest": {
    "autocomplete": {
      "prefix": "To bo",
      "completion": {
        "field": "text_entry",
        "fuzzy": {
          "fuzziness": "AUTO"
        }
      }
    }
  }
}

fuzzy 参数 #

参数说明默认值
fuzziness编辑距离(AUTO012AUTO
transpositions是否允许字符交换true
min_length开始模糊匹配的最小输入长度3
prefix_length不参与模糊的前缀字符数1
unicode_aware是否按 Unicode 字符计算编辑距离false

正则补全 #

支持基于正则表达式的补全匹配:

GET shakespeare/_search
{
  "suggest": {
    "autocomplete": {
      "regex": "To b[aeiou].*",
      "completion": {
        "field": "text_entry"
      }
    }
  }
}

权重控制 #

通过 inputweight “运营"特定建议词:

PUT shakespeare/_doc/1
{
  "text_entry": {
    "input": ["To be, or not to be: that is the question:"],
    "weight": 10
  }
}

权重更高的候选会优先排在补全结果前面。


Term Suggester(拼写纠正) #

Term Suggester 基于编辑距离对单个词项提供拼写纠正建议:

GET shakespeare/_search
{
  "suggest": {
    "spell-check": {
      "text": "lief",
      "term": {
        "field": "text_entry"
      }
    }
  }
}

返回按 score 排序的纠正候选,freq 表示该词在索引中出现的次数。分数越高建议越好。


Phrase Suggester(短语纠正) #

Phrase Suggester 使用 N-gram 语言模型对整个短语进行纠正,实现"Did you mean …?“功能。

需要先配置 shingle 过滤器来构建词级 N-gram:

PUT shakespeare
{
  "settings": {
    "analysis": {
      "analyzer": {
        "trigram": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "shingle"]
        }
      },
      "filter": {
        "shingle": {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 3
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text_entry": {
        "type": "text",
        "fields": {
          "trigram": {
            "type": "text",
            "analyzer": "trigram"
          }
        }
      }
    }
  }
}

使用 phrase 建议:

POST shakespeare/_search
{
  "suggest": {
    "text": "That the qution",
    "simple_phrase": {
      "phrase": {
        "field": "text_entry.trigram"
      }
    }
  }
}

返回纠正后的短语:"that is the question"