Elasticsearch权威指南:邻近匹配与Shingles技术解析

Elasticsearch权威指南:邻近匹配与Shingles技术解析

elasticsearch-definitive-guide The Definitive Guide to Elasticsearch elasticsearch-definitive-guide 项目地址: https://gitcode.com/gh_mirrors/el/elasticsearch-definitive-guide

引言

在全文搜索领域,精确匹配相关联的词语是一个常见需求。Elasticsearch提供了短语查询和邻近查询,但这些方法存在一定局限性。本文将深入探讨一种更灵活的解决方案——Shingles技术,它能有效捕捉词语间的关联性,提升搜索质量。

传统方法的局限性

短语查询和邻近查询(使用slop参数)虽然有用,但存在两个主要问题:

  1. 过度严格:要求所有查询词必须出现在文档中
  2. 丢失关联性:当使用slop放宽词序限制时,无法确定词语间的具体关联关系

例如,搜索"Sue ate alligator"时,我们无法区分是"Sue ate"还是"alligator ate"这样的具体关系。

Shingles技术原理

Shingles(词片)是一种将相邻词语组合索引的技术,主要分为两种:

  1. Bigrams(二元组):索引相邻的两个词,如["sue ate", "ate the", "the alligator"]
  2. Trigrams(三元组):索引相邻的三个词,如["sue ate the", "ate the alligator"]

为什么选择Bigrams

虽然Trigrams能提供更高精度,但会显著增加索引中的唯一词项数量。实践表明,Bigrams在大多数场景下已经足够,能在精度和性能间取得良好平衡。

实现Shingles搜索

1. 创建Shingles分析器

我们需要在索引时配置自定义分析器:

PUT /my_index
{
    "settings": {
        "analysis": {
            "filter": {
                "my_shingle_filter": {
                    "type": "shingle",
                    "min_shingle_size": 2,
                    "max_shingle_size": 2,
                    "output_unigrams": false
                }
            },
            "analyzer": {
                "my_shingle_analyzer": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": ["lowercase", "my_shingle_filter"]
                }
            }
        }
    }
}

关键参数说明:

  • output_unigrams: false:确保只输出bigrams
  • min/max_shingle_size: 2:指定生成二元组

2. 使用多字段映射

为了同时保留unigrams和bigrams,我们采用多字段映射:

PUT /my_index/_mapping/my_type
{
    "my_type": {
        "properties": {
            "title": {
                "type": "string",
                "fields": {
                    "shingles": {
                        "type": "string",
                        "analyzer": "my_shingle_analyzer"
                    }
                }
            }
        }
    }
}

这种设计允许我们:

  • 主字段(title):索引原始单词
  • 子字段(title.shingles):索引bigrams

3. 构建查询

实际搜索时,我们组合使用两个字段:

GET /my_index/my_type/_search
{
   "query": {
      "bool": {
         "must": {
            "match": {
               "title": "the hungry alligator ate sue"
            }
         },
         "should": {
            "match": {
               "title.shingles": "the hungry alligator ate sue"
            }
         }
      }
   }
}

查询逻辑:

  • must子句:确保基本匹配
  • should子句:通过bigrams提升相关文档的评分

性能考量

Shingles技术相比短语查询有显著优势:

  1. 查询效率:与简单match查询相当,远高于短语查询
  2. 索引开销:需要额外存储空间,但符合"一次写入多次读取"的最佳实践
  3. 灵活性:不要求查询词顺序严格匹配,同时能捕捉词语关联

实际应用建议

  1. 数据建模:根据业务需求选择bigrams或trigrams
  2. 相关性调优:可以调整shingles字段的boost值控制其影响程度
  3. 组合使用:将shingles与其他技术(如同义词、词干提取)结合使用

总结

Shingles技术为Elasticsearch提供了一种高效实现邻近匹配的方法,它克服了传统短语查询的局限性,在保持查询性能的同时,显著提升了搜索结果的相关性。通过合理配置分析器和映射,开发者可以在各种搜索场景中灵活应用这一技术。

elasticsearch-definitive-guide The Definitive Guide to Elasticsearch elasticsearch-definitive-guide 项目地址: https://gitcode.com/gh_mirrors/el/elasticsearch-definitive-guide

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芮瀚焕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值