本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
索引时输入即搜索编辑
设置索引时输入即搜索的第一步是需要定义好分析链, 我们已在 配置分析器 中讨论过,这里会对这些步骤再次说明。
准备索引编辑
第一步需要配置一个自定义的 edge_ngram token 过滤器,称为 autocomplete_filter :
{
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
}
}这个配置的意思是:对于这个 token 过滤器接收的任意词项,过滤器会为之生成一个最小固定值为 1 ,最大为 20 的 n-gram 。
然后会在一个自定义分析器 autocomplete 中使用上面这个 token 过滤器:
{
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}这个分析器使用 standard 分词器将字符串拆分为独立的词,并且将它们都变成小写形式,然后为每个词生成一个边界 n-gram,这要感谢 autocomplete_filter 起的作用。
创建索引、实例化 token 过滤器和分析器的完整示例如下:
PUT /my_index
{
"settings": {
"number_of_shards": 1,
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}
}
}参考 被破坏的相关度 。 | |
首先自定义 token 过滤器。 | |
然后在分析器中使用它。 |
可以拿 analyze API 测试这个新的分析器确保它行为正确:
GET /my_index/_analyze?analyzer=autocomplete quick brown
结果表明分析器能正确工作,并返回以下词:
-
q -
qu -
qui -
quic -
quick -
b -
br -
bro -
brow -
brown
可以用 update-mapping API 将这个分析器应用到具体字段:
PUT /my_index/_mapping/my_type
{
"my_type": {
"properties": {
"name": {
"type": "string",
"analyzer": "autocomplete"
}
}
}
}现在创建一些测试文档:
POST /my_index/my_type/_bulk
{ "index": { "_id": 1 }}
{ "name": "Brown foxes" }
{ "index": { "_id": 2 }}
{ "name": "Yellow furballs" }查询字段编辑
如果使用简单 match 查询测试查询 “brown fo” :
GET /my_index/my_type/_search
{
"query": {
"match": {
"name": "brown fo"
}
}
}可以看到两个文档同时 都能 匹配,尽管 Yellow furballs 这个文档并不包含 brown 和 fo :
{
"hits": [
{
"_id": "1",
"_score": 1.5753809,
"_source": {
"name": "Brown foxes"
}
},
{
"_id": "2",
"_score": 0.012520773,
"_source": {
"name": "Yellow furballs"
}
}
]
}如往常一样, validate-query API 总能提供一些线索:
GET /my_index/my_type/_validate/query?explain
{
"query": {
"match": {
"name": "brown fo"
}
}
}explanation 表明查询会查找边界 n-grams 里的每个词:
name:b name:br name:bro name:brow name:brown name:f name:fo
name:f 条件可以满足第二个文档,因为 furballs 是以 f 、 fu 、 fur 形式索引的。回过头看这并不令人惊讶,相同的 autocomplete 分析器同时被应用于索引时和搜索时,这在大多数情况下是正确的,只有在少数场景下才需要改变这种行为。
我们需要保证倒排索引表中包含边界 n-grams 的每个词,但是我们只想匹配用户输入的完整词组( brown 和 fo ),
可以通过在索引时使用 autocomplete 分析器,并在搜索时使用 standard 标准分析器来实现这种想法,只要改变查询使用的搜索分析器 analyzer 参数即可:
GET /my_index/my_type/_search
{
"query": {
"match": {
"name": {
"query": "brown fo",
"analyzer": "standard"
}
}
}
}换种方式,我们可以在映射中,为 name 字段分别指定 index_analyzer 和 search_analyzer 。因为我们只想改变 search_analyzer ,这里只要更新现有的映射而不用对数据重新创建索引:
PUT /my_index/my_type/_mapping
{
"my_type": {
"properties": {
"name": {
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "standard"
}
}
}
}如果再次请求 validate-query API ,当前的解释为:
name:brown name:fo
再次执行查询就能正确返回 Brown foxes 这个文档。
因为大多数工作是在索引时完成的,所有的查询只要查找 brown 和 fo 这两个词,这比使用 match_phrase_prefix 查找所有以 fo 开始的词的方式要高效许多。
边界 n-grams 与邮编编辑
边界 n-gram 的方式可以用来查询结构化的数据,
比如 本章之前示例 中的邮编(postcode)。当然 postcode 字段需要 analyzed 而不是 not_analyzed ,不过可以用 keyword 分词器来处理它,就好像他们是 not_analyzed 的一样。
keyword 分词器是一个非操作型分词器,这个分词器不做任何事情,它接收的任何字符串都会被原样发出,因此它可以用来处理 not_analyzed 的字段值,但这也需要其他的一些分析转换,如将字母转换成小写。
下面示例使用 keyword 分词器将邮编转换成 token 流,这样就能使用边界 n-gram token 过滤器:
Getting Started Videos
备份地址:http://www.lvesu.com/blog/es/_index_time_search_as_you_type.html