`

Elasticsearch 部分匹配 (一) - 前缀查询

阅读更多

原文链接:http://blog.csdn.net/dm_vincent/article/details/42001851

 

部分匹配(Partial Matching)

敏锐的读者可能已经发现到目前为止,介绍的查询都是在整个词条层面进行操作的。匹配的最小单元必须是一个词条。你只能找到存在于倒排索引(Inverted Index)中的词条。

但是如果你想匹配词条的一部分,而不是整个词条呢?部分匹配(Partial Matching)允许用户指定词条的一部分然后找到含有该部分的任何单词。

匹配词条一部分这一需求在全文搜索引擎领域比你想象的要不那么常见。如果你有SQL的背景,你可能有过使用下面的SQL语句来实现一个简单的全文搜索功能的经历:

WHERE text LIKE "*quick*"
      AND text LIKE "*brown*"
      AND text LIKE "*fox*"

当然,通过ES我们可以借助分析过程(Analysis Process)和倒排索引来避免这种"蛮力"技术。为了同时匹配"fox"和"foxes",我们可以简单地使用一个词干提取器,然后将词干进行索引。这样就没有必要进行部分匹配了。

即便如此,在某些场合下部分匹配还是有作用的。常见的用例比如:

  • 匹配邮政编码,产品序列号,或者其它以某个特定前缀开头的或者能够匹配通配符甚至正则表达式的not_analyzed值。
  • 即时搜索(Search-as-you-type) - 在用户完成搜索词条的输入前就展示最有可能的结果。
  • 匹配德语或者荷兰语这一类语言,它们韩哟长复合单词,比如Weltgesundheitsorganisation(World Health Organization)。

我们以针对精确值not_analyzed字段的前缀匹配开始,介绍部分匹配的技术。

 

 

 

邮政编码和结构化数据

 

我们以英国的邮政编码来说明如何在结构化数据上使用部分匹配。英国邮政编码是一个定义清晰的结构。比如,W1V 3DG这个邮政编码可以被分解成以下几个部分:

  • W1V:这个部分表明了邮政地域和地区(Postal Area and District):
    • W 表明了地域(Area),使用一个或者两个字母。
    • 1V 表明了地区(District),使用一个或者两个数字,可能跟随一个字母。
  • 3DG:该部分表明了街道或者建筑:
    • 3 表明了区域(Sector),使用一个数字。
    • DG 表明了单元,使用两个字母。

假设我们将邮政编码索引为精确值的not_analyzed字段,因此我们可以创建如下索引:

PUT /my_index
{
    "mappings": {
        "address": {
            "properties": {
                "postcode": {
                    "type":  "string",
                    "index": "not_analyzed"
                }
            }
        }
    }
}

然后索引一些邮政编码:

PUT /my_index/address/1
{ "postcode": "W1V 3DG" }

PUT /my_index/address/2
{ "postcode": "W2F 8HW" }

PUT /my_index/address/3
{ "postcode": "W1F 7HW" }

PUT /my_index/address/4
{ "postcode": "WC1N 1LZ" }

PUT /my_index/address/5
{ "postcode": "SW5 0BE" }

现在我们的数据就准备就绪了。

 

 

 

前缀查询(Prefix Query)

 

我们可以通过一个简单的prefix查询来得到所有以W1开头的邮政编码:

GET /my_index/address/_search
{
    "query": {
        "prefix": {
            "postcode": "W1"
        }
    }
}

prefix查询是一个工作在词条级别的低级查询。它不会在搜索前对查询字符串进行解析。它假设用户会传入一个需要查询的精确前缀。

TIP

默认情况下,prefix查询不会计算相关度分值。它只是进行文档匹配,匹配的文档的分值为1。其实,相比查询它更像一个过滤器。prefix查询和prefix过滤器的唯一区别在于过滤器可以被缓存。

之前,我们提到过"你只能找到存在于倒排索引中的词条",但是对于这些邮政编码我们并没有进行任何特殊处理;每个邮政编码只是被当做精确值被简单地索引。那么prefix查询是如何工作的呢?

记住倒排索引是由唯一词条得有序列表构成的(此种情况下,即邮政编码)。对于每个词条,它会列举所有含有该词条的文档ID。对于我们的示例文档,倒排索引如下所示:

Term:          Doc IDs:
-------------------------
"SW5 0BE"    |  5
"W1F 7HW"    |  3
"W1V 3DG"    |  1
"W2F 8HW"    |  2
"WC1N 1LZ"   |  4
-------------------------

为了支持前缀匹配,查询会执行以下的步骤:

  1. 遍历词条列表并找到以W1开头的词条。
  2. 收集对应的文档ID。
  3. 移动到下一个词条。
  4. 如果该词条也以W1开头,那么重复步骤2;否则结束操作。

尽管以上的步骤对于我们的小例子而言能很好地工作,想象一下当倒排索引含有一百万个以W1开头的邮政编码时的情景,prefix查询需要访问一百万个词条来得到结果。

而前缀越短,就意味着需要访问越多的词条。如果我们查询前缀为W,而不是W1的词条,可能会匹配多达一千万个词条。

注意

prefix查询和过滤器对于即时(Ad-hoc)的前缀匹配是有用处的,但是在使用它们的时候需要小心。对于拥有少量词条的字段可以随意地使用,但是它们的扩展性较差,可能会让你的集群承受过多的压力。可以通过使用一个较长的前缀来限制它们对于集群的影响;这能够减少需要访问的词条的数量。

在本章的稍后部分,我们会介绍一种让前缀匹配更具效率的索引期间解决方案。但是首先,让我们看看两个相关的查询:wildcard以及regexp查询。

 

 

分享到:
评论

相关推荐

    深入Elasticsearch:掌握前缀查询的艺术

    前缀查询作为Elasticsearch中的一个重要特性,允许我们基于字段值的前缀来进行搜索和过滤。这种查询方式尤其适用于那些需要根据部分输入来获取完整结果的场景,比如在搜索引擎的自动补全功能中。 在Elasticsearch中...

    Spring Boot整合ElasticSearch和Mysql 附案例源码.docx

    - 前缀查询:利用ElasticSearch的前缀匹配功能实现基于首字母的搜索。 - 自动补全:提供自动补全功能,增强用户体验。 #### 三、项目搭建 - **环境配置:** - **Java版本:** 1.8 - **Spring Boot版本:** ...

    探索未知:在Elasticsearch中执行模糊查询

    ### 探索未知:在Elasticsearch中执行模糊查询 #### Elasticsearch简介 Elasticsearch是一个基于Lucene构建的开源、分布式、RESTful风格的搜索和分析引擎。它被广泛应用于处理大量的数据集,特别是那些需要实时...

    深入解析:如何在 Elasticsearch 中执行布尔查询

    例如,查询只需要满足“标题包含 Elasticsearch”或者“作者不是 John Doe”中的任意一个条件即可。 3. **NOT**:表示指定的子查询必须排除在外。例如,查询结果中不能出现“作者是 John Doe”的记录。 4. **FILTER*...

    ElasticSearch高级和进阶(高清视频教程).rar

    Elasticsearch,简称ES,是一款基于Lucene的分布式、RESTful风格的搜索和数据分析引擎,广泛应用于大数据处理和全文检索领域。本教程将深入探讨Elasticsearch的高级特性和进阶技巧,帮助用户提升对这一强大工具的...

    Elasticsearch-Autocomplete-Text-Box:使用自动完成文本框实现 Elasticsearch

    5. **查询请求**:当用户在文本框中输入时,发送一个带有`suggest`参数的GET或POST请求到Elasticsearch。例如: ```json { "suggest": { "text": "用户输入", "autocomplete-suggestion": { "prefix": "用户...

    elasticsearch笔记1

    在Elasticsearch中,查询是检索数据的核心操作,本笔记主要介绍了多种查询方式,帮助我们更有效地从索引中获取匹配的数据。 1. **全部查询**: 使用`match_all`查询可以返回索引中的所有文档。在示例中,GET请求`...

    es-dsl-cheatsheet:Elasticsearch 查询 DSL 备忘单

    Elasticsearch(ES)是一种强大的分布式搜索和分析引擎,广泛应用于日志分析、信息检索、实时数据分析等领域。它的查询DSL(Domain Specific Language)是用于构建复杂搜索和过滤条件的语言,允许用户以JSON格式进行...

    Elasticsearch.Server.3rd.Edition

    本书全面介绍了 Elasticsearch 的基础知识和进阶技巧,包括全文检索的基础、输入数据的分析方法、索引和查询的核心技术、Elasticsearch 的基础设施概念,以及如何安装和配置 Elasticsearch 集群。此外,还详细讲解了...

    Elastic Search学习笔记

    前置过滤是 Elasticsearch 中的一种特殊过滤类型,它主要用于匹配字符串前缀。这种方式非常适合用于快速筛选出具有相同前缀的文档集合。 **示例命令**: ```bash curl -XGET localhost:9200/baselinelog/bllog/_...

    Elasticsearch 7 探索之路_131实用知识库分享

    Elasticsearch 提供了 Search-API,用于实现搜索功能,Search-API 提供了多种搜索方式,包括精准搜索、模糊搜索、前缀搜索等。 9. Mapping Elasticsearch 提供了 Mapping 功能,用于将文档数据映射到索引中,以便于...

    04 - Elasticsearch+Neo4j在档案领域的探索与实践 - 兰小伟 重庆 2024.4.27

    - **TermPrefixQuery**:支持前缀匹配,对于部分已知关键词的情况特别有用。 - **Ngram分词**:用于生成短语或单词的不同片段,有助于扩展查询范围。 - **词嵌入技术**:通过词向量表示词语,支持语义相似性的搜索,...

    Python-ElasticSearch搜索查询的讲解

    Python的elasticsearch库提供了丰富的API接口,支持多种查询方式,包括但不限于全文检索、精确匹配、范围查询等。 #### 基础查询 1. **查询所有数据** - 可以直接调用`es.search`方法,指定索引名和文档类型即可...

    ElasticSearch可扩展的开源弹性搜索解决方案.docx

    - **查询DSL**:将多个简单的查询封装为一个 JSON 对象发送给 ElasticSearch,便于执行复杂的搜索操作。 - **示例查询**: ```bash curl -X GET 'localhost:9200/library/book/_search?q=title:crime&pretty=true...

    elasticsearch api的详细讲解,非常详细 有学习价值

    ### Elasticsearch API 详细讲解 ...对初学者而言,理解以上聚合查询、复合查询和基础查询的各种用法和适用场景,有助于深入掌握Elasticsearch的搜索和数据处理能力,进一步能够根据实际业务需求进行优化和定制。

    Elasticsearch实现复合查询高亮结果功能

    总结起来,Elasticsearch的复合查询和高亮功能使我们能够构建复杂的搜索逻辑,并且在结果中清晰地展示匹配的部分,提升用户体验。在实际应用中,根据业务需求调整查询条件和高亮配置是至关重要的。通过熟练掌握这些...

    索引构建秘籍:如何定义 Elasticsearch 中的映射?

    在 Elasticsearch 中,映射主要由以下几个部分组成: 1. **字段名称**:每个字段都有唯一的标识符,用以区分不同的数据项。 2. **字段类型**:定义了字段的数据类型,如`text`、`keyword`、`integer`等。 3. **字段...

Global site tag (gtag.js) - Google Analytics