ES系列08:Full text queries(3) query_string系列

前面为大家介绍了:【ES系列06:ik分词+Full text queries 之match queryES系列07:match_phrase与match_phrase_prefix query】。今天TeHero为大家分享 Full text queries 剩余的4种查询语句multi_match query、common terms query、query_string query、simple_query_string query,同时结合倒排序索引原理,将DSL语句转化为sql语句,方便大家理解学习。

ps:文章最后有关于 Full text queries 所有查询的总结!

原文链接:【排版好看点】ES系列08:Full text queries(3) query_string系列

image

image.gif
                                                                 Full Text queries 系列知识脑图

ps:上图的xmind文件获取方式见评论区!

在学习本节之前,请先参考:ES系列07:match_phrase与match_phrase_prefix query,完成数据导入和倒排列表的创建。

ps:如果看不懂上图,请先阅读学习:ElasticSearch系列05:倒排序索引与分词Analysis

一、multi_match query -match 的多字段版本

结合之间的match语法,这个是很好理解的:ES系列06:ik分词+Full text queries 之match query

# 1、同时查询  "content", "content.ik_smart_analyzer",得到文档3
GET /tehero_index/_doc/_search
{
  "query": {
    "multi_match": {
      "query": "系统",
      "fields": [
        "content",
        "content.ik_smart_analyzer"
      ]
    }
  }
}

# 2、同时查询 所有字段 得到所有文档
GET /tehero_index/_doc/_search
{
  "query": {
    "multi_match": {
      "query": "系统",
      "fields": [
        "content",
        "content.ik_smart_analyzer",
        "content.ik_max_analyzer"
      ]
    }
  }
}

需要注意的是,多个Fields之间的查询关系是 or ,就相当于mysql 的 【where 字段1=“检索词”or 字段2 = “检索词” or 字段3 = “检索词”】

字段^数字:表示增强该字段(权重影响相关性评分):先知道有这么个属性即可,相关性评分是一个重点和难点,后面再系统讲解。

GET /tehero_index/_doc/_search
{
  "query": {
    "multi_match": {
      "query": "系统",
      "fields": [
        "content",
        "content.ik_smart_analyzer^3",
        "content.ik_max_analyzer"
      ]
    }
  }
}
image.gif

1.1 multi_match query 对应的sql语句

ET /tehero_index/_doc/_search
{
  "query": {
    "multi_match": {
      "query": "系统学",
      "fields": [
        "content.ik_smart_analyzer",
        "content.ik_max_analyzer"
      ]
    }
  }
}
image.gif
DSL执行分析:

1)检索关键词“系统学”,根据搜索的field对应的分词器,进行不同的分词: "content.ik_smart_analyzer"字段(简称field1)分词,得到一个Token【系统学】;"content.ik_max_analyzer"字段(简称field2)分词,得到三个Token【系统学,系统,学】。

2)使用检索词的Token在对应的field的PostingList中进行检索,等价于sql语句:【select id from field1-PostingList where Token = “系统学”】【select id from field2-PostingList where Token in ("系统学","系统","学")】;

3)最后再对检索出来的两个 PostingList 做一个合并操作,得到文档。

二、common terms query——对停顿词的检索优化(简单了解即可)

对于这个语法,先了解即可,主要还是用于英语,对于中文,实用性不大。(ps:以下内容翻译至官网) 该查询将检索词分割分为两组:更重要(即低频率而言)和不太重要的(即,高频率而言,如已停用词)。首先,它搜索与更重要的术语匹配的文档。这些术语出现在较少的文档中,并且对相关性具有更大的影响。然后,它对不那么重要的词执行第二次查询,这些词经常出现并且对相关性影响很小。但是,它是在第一个查询的结果集基础上,而不是计算所有匹配文档的相关性得分。这样,高频项可以改善相关性计算,而无需付出性能不佳的代价。如果查询仅由高频词组成,则将单个查询作为AND(合并)查询执行,换句话说,所有词都是必需的。

# 文档频率大于0.1%的单词(例如"this"和"is")将被视为通用术语。
GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant as a cartoon",
                "cutoff_frequency": 0.001,
                "low_freq_operator": "and"
            }
        }
    }
}

等价于:
GET /_search
{
    "query": {
        "bool": {
            "must": [
            { "term": { "body": "nelly"}},
            { "term": { "body": "elephant"}},
            { "term": { "body": "cartoon"}}
            ],
            "should": [
            { "term": { "body": "the"}},
            { "term": { "body": "as"}},
            { "term": { "body": "a"}}
            ]
        }
    }
}
image.gif

总结:common terms query 目的:在保证检索性能的前提下,提高搜索结果的准确度。(能检索到the a 等高频率的停顿词)

# 简单理解,对 the a as 等进行分词
GET /_analyze
{
  "text": ["the a as"],
  "analyzer": "ik_max_word"
}
结果:为空,因为这些停顿词都被过滤掉了,这个时候就使用 common terms query,检索到这些词
{
  "tokens": []
}
image.gif

三、query_string query

允许我们在单个查询字符串中指定AND | OR | NOT条件,同时也和 multi_match query 一样,支持多字段搜索。

# 1、检索同时包含Token【系统学、es】的文档,结果为空
GET /tehero_index/_doc/_search
{
    "query": {
        "query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统学 AND es"
        }
    }
}
# 2、检索包含Token【系统学、es】二者之一的文档,能检索到文档1、2、4
GET /tehero_index/_doc/_search
{
    "query": {
        "query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统学 OR es"
        }
    }
}
image.gif

有了前面的基础,query_string query是非常容易理解的,语句1等价于sql语句【where Token = “系统学”and Token = “es” 】

注意点:1、中间的连接词【AND | OR | NOT】必须是全大写;

2、各个检索词依然会被对应的分词器分词,单个检索词就相当于match query。

GET /tehero_index/_doc/_search
{
    "query": {
        "query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统编程 OR es"
        }
    }
}
image.gif

就比如上例,单个检索词“系统编程”还是会被分词器“ik_smart”分词为两个Token【系统、编程】,同时对这个检索词“系统编程”执行 match query查询,所以上面的DSL会把所有的文档都检索出来。

四、simple_query_string query

类似于query_string ,但是会忽略错误的语法,永远不会引发异常,并且会丢弃查询的无效部分。

simple_query_string支持以下特殊字符:

+ 表示与运算,相当于query_string 的 AND
| 表示或运算,相当于query_string  的 OR
- 取反单个令牌,相当于query_string 的 NOT
"" 表示对检索词进行 match_phrase query
* 字词末尾表示前缀查询
image.gif
结合DSL语句简单理解下:

4.1 + 表示与运算,相当于query_string 的 AND

# 1、检索到文档4
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统学 + 间隔"
        }
    }
}
image.gif

4.2 | 表示或运算,相当于query_string 的 OR

# 2、检索到文档1、2、4
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统学 | 间隔"
        }
    }
}
image.gif

4.3 - 取反单个令牌,相当于query_string 的 NOT

# 3、检索到文档1、2
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统学 -间隔",
            "default_operator": "and"
        }
    }
}
image.gif

注意:参数"default_operator": "and"。该参数的默认值为or。 上述DSL对应的sql语句为:【where Token = 系统学 and Token <> 间隔】

4.4 "" 表示对检索词进行 match_phrase query

# 4、检索到文档2
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "\"系统学编程关注\""
        }
    }
}
# 5、检索到所有文档
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统学编程关注"
        }
    }
}
image.gif

分析:"query" : ""系统学编程关注"",会对检索词执行 match_phrase query !

4.5 * 字词末尾表示前缀查询 -match_phrase_prefix query

# 6、检索到文档 3
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统"
        }
    }
}
# 6、检索到所有文档,等价于match_phrase_prefix query
GET /tehero_index/_doc/_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content.ik_smart_analyzer"],
            "query" : "系统*"
        }
    }
}
image.gif

五、总结

到此,我们已经学完了 Full text queries 所有的查询语句:

1)match query:用于执行全文查询的标准查询,包括模糊匹配和短语或接近查询。重要参数:控制Token之间的布尔关系:operator:or/and

2)match_phrase query:与match查询类似,但用于匹配确切的短语或单词接近匹配。重要参数:Token之间的位置距离:slop 参数

3)match_phrase_prefix query:与match_phrase查询类似,但是会对最后一个Token在倒排序索引列表中进行通配符搜索。重要参数:模糊匹配数控制:max_expansions 默认值50,最小值为1

4)multi_match query:match查询 的多字段版本。该查询在实际中使用较多,可以降低DSL语句的复杂性。同时该语句有多个查询类型,后面TeHero会专门进行讲解。

5)common terms query:对于中文检索意义不大。

6)query_string query 和 simple_query_string query,其实就是以上 query语句的合集,使用非常灵活,DSL编写简单。但是,TeHero认为这两个查询语句,有一个很明显的弊端:类似于sql注入。如果用户在检索词输入了对应的“关键字”【比如OR、】等,用户将获取到本不应该被查询到的数据。慎用!*

下期预告:Term-level queries(精确匹配)

ElasticSearch系列01:如何系统学习ES

●ES系列05:倒排序索引与分词Analysis

ES系列06:ik分词+Full text queries 之match query

ES系列07:match_phrase与match_phrase_prefix query

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,100评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,862评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,993评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,309评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,303评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,421评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,830评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,501评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,689评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,506评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,564评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,286评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,826评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,875评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,114评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,705评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,269评论 2 341