引言

今天再读庄子的《逍遥游》,其中鲲鹏之扶摇直上九万里之气势,蜩(tiao)与学鸠之渺小之对比,令人印象深刻,并对鲲鹏之志心生向往。而郭象在注《庄子》卷中却说,"苟足于其性,则虽大鹏无以自贵于小鸟,小鸟无羡于天池,而荣愿有余矣。故小大虽殊,逍遥一也。"观看自身,虽然不是什么领导,老总,但也完全不必感到为职业生涯忧虑,只要热爱程序员这个工作,享受编码的乐趣,做到 80 岁又有何妨。

书归正传,今天我们聊聊 Match Phase Query。

Match Phase Query

match_phrase 查询针对的是一个语句,比如 "like football", 分析时也会将整个语句作为整体,而不会像上篇的 match 查询 会将整个语句拆分为单个词条。

举个例子,创建一个 match_phase type 并塞进去一个文档, message 是 I like swimming and riding!

PUT matchphasetest
{} PUT matchphasetest/_mapping/match_phase
{
"properties": {
"message": {
"type": "text"
}
}
} PUT matchphasetest/match_phase/1
{
"message": "I like swimming and riding!"
} GET matchphasetest/_search
{
"query": {
"match_phrase": {
"message": "I like swimming"
}
}
}

默认使用 match_phrase 时会精确匹配查询的短语,需要全部单词和顺序要完全一样,标点符号除外。

slop 参数

这种精确匹配在大部分情况下显得太严苛了,有时我们想要包含 ""I like swimming and riding!"" 的文档也能够匹配 "I like riding"。这时就要以用到 "slop" 参数来控制查询语句的灵活度。

slop 参数告诉 match_phrase 查询词条相隔多远时仍然能将文档视为匹配 什么是相隔多远? 意思是说为了让查询和文档匹配你需要移动词条多少次?

以 "I like swimming and riding!" 的文档为例,想匹配 "I like riding",只需要将 "riding" 词条向前移动两次,因此设置 slop 参数值为 2, 就可以匹配到。

GET matchphasetest/_search
{
"query": {
"match_phrase": {
"message": {
"query": "I like riding",
"slop": 2
}
}
}
}

analyzer 参数

match_phrase 语句也可以设置 analyzer 参数来定义查询语句时对其中词条执行的分析过程。

默认情况下,使用的是创建 mapping 时的分析器,如果没有指定就会使用默认的查询分析器。这里举个例子(只是如何使用)

GET /_search
{
"query": {
"match_phrase" : {
"message" : {
"query" : "this is a test",
"analyzer" : "my_analyzer"
}
}
}
}

zero terms query

match_phrase 也接受 zero_terms_query 为参数,使用方式和 match查询语句相同

Match Phrase 前缀查询

match_phrase_prefixmatch_phrase 用法是一样的,区别就在于它允许对最后一个词条前缀匹配。以上节的数据为例,查询 I like sw 就能匹配到

I like swimming and riding

GET matchphasetest/_search
{
"query": {
"match_phrase_prefix": {
"message": "I like swi"
}
}
}

max_expansions

官方文档中说 match_phrase_prefix 查询中有个参数 max_expansions 说的是参数 max_expansions 控制着可以与前缀匹配的词的数量,默认值是 50。

I like swi 查询为例,它会先查找第一个与前缀 swi 匹配的词,然后依次查找搜集与之匹配的词(按字母顺序),直到没有更多可匹配的词或当数量超过 max_expansions 时结束。

但是我在使用时,故意造出了数十个以 swi 开头的词,而将 max_expansions 的值设为 10。但是却返回了所有的结果。在 elasitc 官网也有对该问题的讨论, 也是没有找到答案。这个问题作为一个公案权且记下,如果您知道原因,麻烦告诉我,非常感谢。

这里也贴出个例子,以备后面排查

GET matchphaseprefixtest/_search
{
"query": {
"match_phrase_prefix": {
"message": {
"query": "I like sw",
"max_expansions": 10
}
}
}
}

match_phrase_prefix 用起来非常方便,能够实现输入即搜索的效果,但是也会出现问题。 假如说查询 I like s 并且想要匹配 I like swimming ,结果是默认情况下它会搜索出前 50 个组合,如果前 50 个没有 swimming ,那就不会显示出结果。只能是用户继续输入后面的字母才可能匹配出结果。

要实现更好的即使搜索的特性,可以看看 completion suggester

Index-Time Search-as-You-Type 能不能实现。

小结

本文论述了 Match Phase Query 和 Match Phrase 前缀查询 的使用,下文会讲解 Multi Match Query 敬请期待。

参考文档

1.Match Phrase Query

系列文章列表

Query DSL

  1. Query DSL 概要,MatchAllQuery,全文查询简述
  2. Match Query

Java Rest Client API

  1. Elasticsearch Java Rest Client API 整理总结 (一)——Document API
  2. Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
  3. Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries

Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query的更多相关文章

  1. Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了

    目录 引言 构建示例 match operator 参数 analyzer lenient 参数 Fuzziness fuzzniess 参数 什么是模糊搜索? Levenshtein Edit Di ...

  2. Elasticsearch Query DSL 整理总结(四)—— Multi Match Query

    目录 引言 概要 fields 字段 通配符 提升字段权重 multi_match查询的类型 best_fields 类型 dis_max 分离最大化查询 best_fields 维权使者 tie_b ...

  3. Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述

    目录 引言 概要 Query and filter context Match All Query 全文查询 Full text queries 小结 参考文档 引言 虽然之前做过 elasticse ...

  4. elasticsearch入门使用(三) Query DSL

    Elasticsearch Reference [6.2] » Query DSL 参考官方文档 :https://www.elastic.co/guide/en/elasticsearch/refe ...

  5. Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries

    目录 上篇回顾 Building Queries 匹配所有的查询 全文查询 Full Text Queries 什么是全文查询? Match 全文查询 API 列表 基于词项的查询 Term Term ...

  6. Query DSL for elasticsearch Query

    Query DSL Query DSL (资料来自: http://www.elasticsearch.cn/guide/reference/query-dsl/) http://elasticsea ...

  7. Elasticsearch学习笔记(二)Search API 与 Query DSL

    一. Search API eg: GET /mall/product/_search?q=name:productName&sort=price desc 特点:search的请求参数都是以 ...

  8. elasticsearch系列四:搜索详解(搜索API、Query DSL)

    一.搜索API 1. 搜索API 端点地址 从索引tweet里面搜索字段user为kimchy的记录 GET /twitter/_search?q=user:kimchy 从索引tweet,user里 ...

  9. Elasticsearch Query DSL备忘(1)(Constant score query和Bool Query)

    Query DSL (Domain Specific Language),基于json的查询方式 1.Constant score query,常量分值查询,目的就是返回指定的score,一般都结合f ...

随机推荐

  1. Servlet初步认知

    1 背景概述 在近期的公司项目开发的过程中,笔者初步学习Servlet的开发.配置与使用,本文主要介绍了Servlet的相关概念以及优势说明并附上笔者开发简单样例.今天将笔者学习的心得总结出来与大家分 ...

  2. Python 绝技 —— TCP服务器与客户端

    i春秋作家:wasrehpic 0×00 前言 「网络」一直以来都是黑客最热衷的竞技场.数据在网络中肆意传播:主机扫描.代码注入.网络嗅探.数据篡改重放.拒绝服务攻击……黑客的功底越深厚,能做的就越多 ...

  3. GoLang学习之变量定义和初始化

    变量命名原则 go语言的变量名有字母数字和下划线组成,首字母不能为数字,但是字母不仅仅只限于英文字母,所有的UTF-8字符都是可以的. 变量声明和初始化方式 使用var关键字 var a int = ...

  4. underscore.js源码研究(6)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  5. 编译lua-5.3.5时出错解决方法

    问题描述: 执行 make linux test 过程出现错误,错误信息如下: “ lua.c:82:31: fatal error: readline/readline.h: No such fil ...

  6. Swift 里 Array (三) Inspecting an Array

    判断是否为空 使用的是Collection协议里isEmpty的判断. public var isEmpty: Bool { return startIndex == endIndex } start ...

  7. 一步步Cobol 400上手自学入门教程04 - 过程部

    过程部的作用:编写程序要执行的语句,是程序的核心. 结构: 基本语句 INITIALIZE 设置数据项的初始值 ACCEPT 接收从键盘或指定设备上获得输入数据. 例子: 当批处理文件读到调用ACCP ...

  8. postgresql和redis

    redis 和postgresql区别以及其优缺点 一刹那者为一念,二十念为一瞬,二十瞬为一弹指,二十弹指为一罗预,二十罗预为一须臾,一日一夜有三十须臾. 那么,经过周密的计算,一瞬间为0.36 秒, ...

  9. Golang 中哪些值是不可以寻址的

    不可以寻址, 指的是不能通过&获得其地址. golang中不能寻址的可以总结为:不可变的,临时结果和不安全的.只要符合其中任何一个条件,它就是不可以寻址的. 具体为: 常量的值. 基本类型值的 ...

  10. Redis 入门知识

    Redis 的前世今生 Redis的诞生于2008年,由Salvatore Sanfilippo开发.最初作者在开发一个网站时,需要实现一个高性能的队列功能,在使用Mysql无果后,决定自己造一个轮子 ...