29

Elasticsearch从入门到放弃:再聊搜索

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU0NTkzODUyMw%3D%3D&%3Bmid=2247484317&%3Bidx=1&%3Bsn=ccb52dcf4051152a77c61c765c491406
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在前文中我们曾经聊过搜索文档的方法,Elasticsearch 一般适用于读多写少的场景,因此我们需要更多的关注读操作。

Elasticsearch 提供的 Search API 可以分为 URI Search 和 Request Body Search 两大类。从名称上可以直观的看出,URI Search 是使用URI的参数传递参数给 Elasticsearch,Request Body Search 则是将参数放到 Body 中进行传递,下面我们具体来看一下。

URI Search

首先我们来看 URI Search 的一些参数。

  • q 指定查询语句,其使用的是 Query String Syntax

  • df 指定默认字段,如果不指定,则会查询全部字段

  • Sort 对哪些字段进行排序

  • from/size 用于分页

此外,我们还可以通过在请求体中指定 profile 参数来查看查询是如何被执行的。

你可以在Kibana中执行下面的查询来看一下 Elasticsearch 的查询是怎样执行的。

GET /movies/_search?q=2012
{
  "profile": "true"
}

GET /movies/_search?q=title:2012
{
  "profile": "true"
}

GET /movies/_search?q=2012&df=title
{
  "profile": "true"
}

在上面这组查询中,当我们指定了查询字段时, Elasticsearch 使用的 query type 是Term Query。

riuaE3E.png!web

term query

与之对应的还有 Phrase Query。

Term

如果我们的查询条件是 title:(Code Review) ,那么它使用的就是 Term Query,它等价于查询 title 中存在 Code 或 Review 的文档。

Phrase

如果我们的查询条件是 title:"Code Review" 这样用引号引起来的,那么它使用的就是 Phrase Query,它等价于查询同时存在 Code 和 Review 的文档,并且 Code 出现的顺序必须在 Review 之前。

这里你可能会有疑问,为什么 Term Query 前后需要加括号,这是 Elasticsearch 中的分组概念,如果想要像我们说的那样,在 titile 字段中查找存在 Code 或 Review 的文档,那么就必须把它们作为一个分组进行查询。这里你可以自己动手试一下不加括号的情况,看一下 Elasticsearch 会如何执行。

Term Query 中还提供了很多种查询语法,例如我们可以只用 AND、OR、NOT 这样的字符进行布尔操作(需要注意它们都必须大写),也可以使用加号或减号表示 must 和 must not 的概念。同时区间、通配符、甚至是正则表达式查询。

Request Body Search

介绍完 URI Search,我们再一起学习一下 Request Body Search,其实在 Elasticsearch 中,Request Body Search 是更加常用的查询方式。因为它能够支持更多高阶的使用方法。

在 Request Body Search 中,我们同样是用 fromsize 来进行分页,默认的是从0开始,返回10个结果。

排序的方法也是使用 sort ,一般建议在“数字型”或“日期型”字段上进行排序。

对于一些字段比较多的文档,我们并不是每次查询都需要全部的字段,这时候就可以在 body 中加上 _source 字段来进行过滤。 _source 字段可以支持通配符,例如 _source:["name*"] ,查询中就只会返回字段名是 name 开头的字段。

前面我们聊了 Term Query 和 Phrase Query,在 Request Body Search 中,我们使用 Match Query 来进行类似的操作。

GET /movies/_search
{
  "query": {
    "match": {
      "title": "Lord Rings"
    }
  }
}

在这个例子中,Elasticsearch 会帮我们查询的是 title 中有 Lord 或 Rings 的文档,如果想要查询 Lord 和 Rings,我们需要用到 operator 来进行修改。

GET /movies/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Lord Rings",
        "operator": "and"
      }
    }
  },
  "profile": "true"
}

如果要使用 Phrase 查询,只需要把上面的 match 替换为 match_phrase 即可。

在 Phrase 查询中,可以使用 slot 参数来指定可以插入在中间的单词数量。

GET /movies/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "Lord Rings",
        "slop": 2
      }
    }
  },
  "profile": "true"
}

总结

本文我们学习了 Elasticsearch 的两种查询方法:URI Search 和 Request Body Search 。这里更加推荐使用 Request Body Search,因为它可以支持很多高阶用法,这里我们只介绍了一些比较常用的查询方法,包括 Term Query 和 Phrase Query,也介绍了一些字段的用法,包括分页、排序、过滤字段等。当然,Elasticsearch 的 Request Body Search 还支持很多其他参数,由于篇幅限制,就不再一一介绍了,大家在使用时可以自行查阅官方文档。

最后多说一句,关于 Elasticsearch,我也是刚刚接触,欢迎志同道合的同学一起交流。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK