全文检索 query string

query_string 是 ES DSL 查询中最为强大的查询语句,支持非常复杂的语法,适合用来做自己的搜索引擎

一、语法

GET /_search
{
  "query": {
    "query_string": {
      "query": "(new york city) OR (big apple)",
      "default_field": "content"
    }
  }
}

1. 字段名 Field names

在查询中,可以指定字段名,格式为:
语法包含但不限于字段名:值(例如:status:active,字段status,值为active的文档)

        (title:(quick OR brown),字段title出现 quick或 brwon)
        (author:"John Smith",字段author为短语 John Smith)
        (first\ name:Alice,字段“first name”值为 Alice)
        (book.\*:(quick OR brown),字段book.title, book.content或book.date字段包含 quick 或 brown)
        (_exists_:title,字段title 包含任意非空值)

2. 通配符 Wildcards

用于单独的 terms,使用 ? 替换单独字符, * 号替换0到多个字符
例如:qu?ck bro*

【警惕】通配符查询需要使用大量内存,性能很差;另一种情况是以通配符开头的单词,查询起来非常笨重,因为需要遍历所有的terms,避免这一情况,设置参数 allow_leading_wildcard 为false

(此外,纯粹的通配符 * 将被替换为 exists 查询,这是为了提高效率,结果就是,“field:*”会匹配"",如

    {
      "field":  ""
    }

但不会匹配 空值

    {
      "field": null
    }

3. 正则表达式 Regular expressions

正则表达式可以嵌入到 query string中,格式为用 "/" 符号包围正则表达式:

    name:/joh?n(ath[oa]n)/

【注意】, allow_leading_wildcard 参数对正则表达式不起效, /.*n/ 仍然会遍历所有的term

4. 模糊匹配 Fuzziness

执行 fuzzy 查询,使用 ~ 操作符

    quikc~ brwn~ foks~

默认的编辑距离是2,但是一般编辑距离1就可以解决 80% 的认类错误拼写,可以指定距离1:

    quikc~1

将 fuzziness 和通配符混合是不支持的,一旦混合,其中一个操作符将失效,例如搜索 app*~1不应用 fuzzy 操作符

5. 邻近搜索 Proximity searches

短语查询(例如 "john smith")期望所有 terms 的顺序不变,但邻近查询允许指定单词离得稍微远一些,或有不同的顺序。 fuzzy 查询可以指定字符在单词中的编辑距离,同样,邻近搜索允许指定短语中单词的最大编辑距离:

    "fox quick"~5

相关度与匹配文本的接近程度有关,比如上述的查询中, "quick fox" 比 "quick brown fox" 相关性更高

6. 范围 Ranges

范围可以指定 date、numeric 或 string 字段,包含范围用方括号指定首尾范围 [min TO max],排除范围用花括号 {min TO max}

    date:[2012-01-01 TO 2012-12-31],2012的所有日期
    count:[1 TO 5],数字 1..5
    tag:{alpha TO omega},在 alpha 到 omega 之间的标签,排除 alpha 和 omega
    count:[10 TO *],从10开始的数字
    date:{* TO 2012-01-01},2012年以前的日期
    count:[1 TO 5} 数字1..4,不包含5

一边没有边界的范围查询可以用以下语法:

    age:>10
    age:>=10
    age:<10
    age:<=10
    age:(>=10 AND <20)
    age:(+>=10 +<20),这里的 +是 AND 操作符

7. 加权 Boosting

使用 boost 操作符 ^ 让一个 term 更相关。例如想找关于 foxes 的文档,但我们更关心 quick foxes:

    quick^2 fox

默认的 boost 值为1,可以用0到1的浮点数来减小相关性
加权重可以用到短语或组:

    "john smith"^2    (foo bar)^4

8. 布尔操作符

默认情况下,一旦一个 term 匹配了,所有 terms 都是可选的。一个搜索 foo bar baz 将找到所有包含这其中一个或多个单词的文档。 default_operator 参数允许修改这个默认布尔逻辑。但布尔操作符可以用来在 query string 中提供更多控制

    +:必须出现
    -:不许出现

例如
quick brown +fox -news,必须出现 fox,不许出现 news,quick 和 brown 的出现会提高相关度
类似的操作符AND, OR, NOT (也写作 &&, ||, !),需要注意他们不遵循优先规则,因此需要用圆括号来区分多操作符中的优先级,例如前面的查询可以写为:

    ((quick AND fox) OR (brown AND fox) OR fox) AND NOT news

用 match 查询可以写为:

    {
        "bool": {
            "must": { "match": "fox"},
            "should": { "match": "quick brown" },
            "must_not": { "match": "news"}
        }
    }

9. 分组 Grouping

圆括号可以用来给多个 terms 或从句分组,也可以用来给一个字段名指定目标,给一个结果修改权重

    (quick OR brown) AND fox
    status:(active OR pending) title:(full text search)^2

10. 转义字符(保留字) Reserved characters

如果你的查询中,存在可以作为操作符的字符,并且你不想用来作为操作符,则需要使用反斜杠来转义。
例如,搜索(1+1)=2,你需要写为"\(1\+1\)\=2",如果写为 JSON作为请求体,需要用到双反斜杠(\\),因为反斜杠是 JSON 字符串的保留转义字符
保留字有:

    + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /

【注意】 < 和 > 符号不能被转义,唯一可以避免误创建范围查询的方法,就是完全不在查询中出现该符号

11. 空格和空查询

空格不被认为是操作符
如果 query string 是空,或者只包含空格,查询将返回空结果

12. 避免使用 query_string 查询 nested 文档

query_string 搜索不返回 nested 文档,想要查询 nested 文档,使用 nested 查询

13. 搜索多字段

使用 fields 参数来执行 query_string 搜索多字段
使用 query_string 来搜索多字段的方法,是扩展每个查询 term 为 OR 从句,如:

 field1:query_term OR field2:query_term | …

例如

    GET /_search
{
  "query": {
    "query_string": {
      "fields": [ "content", "name" ],
      "query": "this AND that"
    }
  }
}

等价于

    GET /_search
{
  "query": {
    "query_string": {
      "query": "(content:this OR name:this) AND (content:that OR name:that)"
    }
  }
}

14. 多字段查询的其他参数

当运行 query_string 查询使用多字段时,支持以下附加参数,类似multi_match
type:
决定如何匹配查询,给文档打分,可用的值有:


image.png

15. 同义词 Synonyms and the query_string query

query_string 用 synonym_graph token filter 支持多 term 同义词扩展,当使用了这个 filter,解析器给每个多 term 同义词创建短语查询

16. minimum_should_match 如何工作

query_string 根据操作符分隔每个查询,构造一个布尔查询作为整个输入。你可以用 minimum_shuould_match 参数来控制 should 从句中有多少需要得到匹配。
布尔查询

      (title:this title:that title:thus)~2

等价于

      GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title"
      ],
      "query": "this that thus",
      "minimum_should_match": 2
    }
  }
}

17. minimum_should_match 如何作用于多字段查询(multiple fields)

布尔查询

      ((content:this content:that content:thus) | (title:this title:that title:thus))

等价于

      GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title",
        "content"
      ],
      "query": "this that thus",
      "minimum_should_match": 2
    }
  }
}

布尔查询

      ((content:this | title:this) (content:that | title:that) (content:thus | title:thus))~2

等价于

      GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title",
        "content"
      ],
      "query": "this OR that OR thus",
      "minimum_should_match": 2
    }
  }
}

18. minimum_should_match 如何作用于 cross-field 搜索

布尔查询

    (blended(terms:[field2:this, field1:this]) blended(terms:[field2:that, field1:that]) blended(terms:[field2:thus, field1:thus]))~2

等价于

    GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title",
        "content"
      ],
      "query": "this OR that OR thus",
      "type": "cross_fields",
      "minimum_should_match": 2
    }
  }
}

二、一级参数

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

推荐阅读更多精彩内容