Elasticsearch - 短语匹配(match_phrase)以及slop参数

短语匹配(Phrase Matching)

就像用于全文搜索的的match查询一样,当你希望寻找邻近的单词时,match_phrase查询可以帮你达到目的。

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": "quick brown fox"
        }
    }
}

和match查询类似,match_phrase查询首先解析查询字符串来产生一个词条列表。然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。一个针对短语quick fox的查询不会匹配我们的任何文档,因为没有文档含有邻接在一起的quick和fox词条。

Tip

match_phrase查询也可以写成类型为phrase的match查询:

"match": {
    "title": {
        "query": "quick brown fox",
        "type":  "phrase"
    }
}

词条位置

当一个字符串被分析时,分析器不仅只返回一个词条列表,它同时也返回原始字符串的每个词条的位置、或者顺序信息:

GET /_analyze?analyzer=standard
Quick brown fox

返回如下:

{
   "tokens": [
      {
         "token": "quick",
         "start_offset": 0,
         "end_offset": 5,
         "type": "<ALPHANUM>",
         "position": 1 
      },
      {
         "token": "brown",
         "start_offset": 6,
         "end_offset": 11,
         "type": "<ALPHANUM>",
         "position": 2 
      },
      {
         "token": "fox",
         "start_offset": 12,
         "end_offset": 15,
         "type": "<ALPHANUM>",
         "position": 3 
      }
   ]
}

 

表示原始字符串各个词条的位置.

位置信息可以被保存在倒排索引(Inverted Index)中,像match_phrase这样位置感知(Position-aware)的查询能够使用位置信息来匹配那些含有正确单词出现顺序的文档,且在这些单词之间没有插入别的单词。

短语是什么

对于匹配了短语"quick brown fox"的文档,下面的条件必须为true:

  • quick、brown和fox必须全部出现在某个字段中。
  • brown的位置必须比quick的位置大1。
  • fox的位置必须比quick的位置大2。

如果以上的任何一个条件没有被满足,那么文档就不能被匹配。

Tip

在内部,match_phrase查询使用了低级的span查询族(Query Family)来执行位置感知的查询。span查询是词条级别的查询,因此它们没有解析阶段(Analysis Phase);它们直接搜索精确的词条。

幸运的是,大多数用户几乎不需要直接使用span查询,因为match_phrase查询通常已经够好了。但是,对于某些特别的字段,比如专利搜索(Patent Search),会使用这些低级查询来执行拥有非常特别构造的位置搜索。

以上参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/phrase-matching.html#phrase-matching

混合起来(Mixing it up)

精确短语(Exact-phrase)匹配也许太过于严格了。也许我们希望含有"quick brown fox"的文档也能够匹配"quick fox"查询,即使位置并不是完全相等的。

我们可以在短语匹配使用slop参数来引入一些灵活性:

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": {
                "query": "quick fox",
                "slop":  1
            }
        }
    }
}

slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配。相隔多远的意思是,你需要移动一个词条多少次来让查询和文档匹配?

我们以一个简单的例子来阐述这个概念。为了让查询quick fox能够匹配含有quick brown fox的文档,我们需要slop的值为1:

            Pos 1         Pos 2         Pos 3
-----------------------------------------------
Doc:        quick         brown         fox
-----------------------------------------------
Query:      quick         fox
Slop 1:     quick                 ↳     fox

尽管在使用了slop的短语匹配中,所有的单词都需要出现,但是单词的出现顺序可以不同。如果slop的值足够大,那么单词的顺序可以是任意的。

为了让fox quick查询能够匹配我们的文档,需要slop的值为3:

            Pos 1         Pos 2         Pos 3
-----------------------------------------------
Doc:        quick         brown         fox
-----------------------------------------------
Query:      fox           quick
Slop 1:     fox|quick  ↵  
Slop 2:     quick      ↳  fox
Slop 3:     quick                 ↳     fox

以上参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/slop.html

### ElasticSearch 中 `match_phrase_prefix` 的使用说明 `match_phrase_prefix` 是一种用于短语匹配并支持前缀模糊查询的功能。它能够将输入的查询字符串进行分词处理,并将最后一个分词视为前缀来查找所有可能的匹配项[^3]。 #### 基本语法 以下是 `match_phrase_prefix` 查询的基本结构: ```json { "query": { "match_phrase_prefix": { "<field>": { "query": "<phrase_with_optional_suffix>" } } } } ``` - `<field>` 表示要搜索的目标字段名称。 - `<phrase_with_optional_suffix>` 是希望匹配短语,其中最后的部分会被当作前缀来进行匹配。 #### 示例解析 假设有一个名为 `kibana_sample_data_ecommerce` 的索引,其数据包含客户姓名 (`customer_full_name`) 字段。如果想找到名字以 "Eddie" 开头的所有记录,则可以运行如下查询: ```json GET kibana_sample_data_ecommerce/_search { "query": { "match_phrase_prefix": { "customer_full_name": { "query": "Eddie" } } } } ``` 上述查询会返回诸如 `"Eddie Underwood"` 和 `"Eddie Utest"` 这样的结果,因为这些条目的名字部分均以 `"Eddie"` 起始。 #### 特性和行为特点 1. **短语匹配** 它不仅限于单个词语的前缀匹配,还允许整个短语作为基础条件的一部分参与筛选过程。例如,在文档中寻找类似于 `"quick brown fox jumps over lazy dog"` 的句子片段时非常有用[^1]。 2. **自动分词机制** 输入的查询串会被依据目标字段所关联的分析器规则拆分成多个独立单元 (tokens)[^4]。之后再利用最后一个 token 实现基于前缀的进一步过滤操作。 3. **性能考量** 尽管功能强大,但由于涉及复杂的内部计算逻辑以及潜在的大规模候选集扫描动作,因此相较于其他简单类型的查询而言可能会消耗更多资源和时间成本。所以在实际应用过程中需要注意优化设计策略以减少不必要的开销影响整体效率表现[^2]。 #### 多字段联合查询扩展案例 除了单独作用在一个特定属性上之外,还可以通过组合方式实现跨多列的同时检索需求。下面展示了一个例子,演示如何同时针对两个不同维度的数据源实施类似的约束限定: ```json GET my_index/_search { "query": { "bool": { "should": [ { "match_phrase_prefix": { "title": { "query": "learning ma" } } }, { "match_phrase_prefix": { "description": { "query": "introduction to elasti" } } } ] } } } ``` 此脚本旨在找出那些标题里含有像 `"learning machine learning"` 或描述中有类似表述为 `"introduction to elastic search engine architecture"` 等特性的项目实例集合。 ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值