返回

基于 N-gram 分词器的 Elasticsearch 高级搜索

后端

在 Elasticsearch 的浩瀚功能海洋中,N-gram 分词器脱颖而出,为用户提供了按单个字母或数字进行分词的强大能力,从而释放了更加精细的搜索潜力。本篇文章将带你深入浅出地探索 N-gram 分词器的用法,助你轻松驾驭 Elasticsearch 的高级搜索功能。

前言

在某些检索场景中,我们需要以极高的粒度对数据进行索引和搜索,例如按单个字母或数字进行检索。默认情况下,Elasticsearch 按照单词对文本进行分词,这对于大多数情况来说已经足够了。然而,当需要更加精细的搜索时,N-gram 分词器就派上了用场。

N-gram 分词器的奥秘

N-gram 分词器可以将文本切分成连续的 n 个字符的片段,而不考虑单词边界。例如,对于单词 "Elasticsearch",一个 3-gram 分词器将产生以下片段:

  • "Ela"
  • "las"
  • "ast"
  • "sti"
  • "ic"
  • "cse"
  • "ear"
  • "rch"

单个字符分词的妙用

在某些情况下,我们需要对单个字符进行分词,以提高搜索的准确性。例如,如果我们有一个包含产品代码的字段,我们希望能够按照单个数字或字母进行搜索。通过使用 1-gram 分词器,我们可以轻松实现此目的:

PUT /products
{
  "mappings": {
    "properties": {
      "product_code": {
        "type": "text",
        "analyzer": "ngram_analyzer"
      }
    }
  }
}
POST /products/_search
{
  "query": {
    "match": {
      "product_code": "AB123"
    }
  }
}

以上查询将匹配所有包含 "AB123" 序列的产品,无论其在字段中的位置如何。

无大小写区分

N-gram 分词器还支持无大小写区分,这在处理大小写不固定的文本时非常有用。通过设置 lowercase 参数为 true,我们可以确保分词器在分词时忽略大小写:

PUT /products
{
  "mappings": {
    "properties": {
      "product_code": {
        "type": "text",
        "analyzer": "ngram_analyzer",
        "params": {
          "lowercase": true
        }
      }
    }
  }
}

实战案例

以下是一个实际案例,展示了 N-gram 分词器在真实场景中的应用:

场景: 有一个包含客户姓名和地址的 Elasticsearch 索引。我们需要实现一个功能,使用户能够通过客户姓名或地址的任何部分进行搜索。

解决方案:

PUT /customers
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "ngram_analyzer",
        "params": {
          "lowercase": true
        }
      },
      "address": {
        "type": "text",
        "analyzer": "ngram_analyzer",
        "params": {
          "lowercase": true
        }
      }
    }
  }
}

现在,用户可以通过客户姓名或地址的任何部分进行搜索,即使其大小写不一致。例如:

POST /customers/_search
{
  "query": {
    "multi_match": {
      "query": "John Doe",
      "fields": ["name", "address"]
    }
  }
}

总结

N-gram 分词器为 Elasticsearch 高级搜索功能增添了一抹亮色。通过按单个字母或数字进行分词,我们可以实现更加精细和准确的搜索,满足各种复杂检索需求。掌握 N-gram 分词器的用法,将极大地提升你的 Elasticsearch 搜索技巧,让数据洞察力更上一层楼。