看完这篇还不会 Elasticsearch 搜索,那我就哭了!
本文主要介绍 ElasticSearch 搜索相关的知识,首先会介绍下 URI Search 和 Request Body Search,同时也会学习什么是搜索的相关性,如何衡量相关性。
Search API
我们可以把 ES 的 Search API 分为两大类,类是 URI Search,用 HTTP GET 的方式在 URL 中使用查询参数已达到查询的目的;另一类为 Request Body Search,可以使用 ES 提供的基于 JSON 格式的格式更加完备的查询语言 Query DSL(Domain Specific Language)
语法范围/_search集群上所有的索引/jvm/_searchjvm/jvm,sql/_searchjvm 和 sql/jvm*/_search以 jvm 开头的索引
在查询的时候需要通过 _search
来标明这个请求为搜索请求,同时可以指定 index,也可以指定多个 index,也可以使用通配符的方式对 index 进行搜索。
下面来看下 URI Search:
URI Search
GET /users/_search?q=username:wupx
URI Search 使用的是 GET 方式,其中 q
指定查询语句,语法为 Query String Syntax,是 KV 键值对的形式;上面的请求表示对 username
字段进行查询,查询包含 wupx
的所有文档。
URI Search 有很多参数可以指定,除了 q
还有如下参数:
- df:默认字段,不指定时会对所有字段进行查询
- sort:根据字段名排序
- from:返回的索引匹配结果的开始值,默认为 0
- size:搜索结果返回的条数,默认为 10
- timeout:超时的时间设置
- fields:只返回索引中指定的列,多个列中间用逗号分开
- analyzer:当分析查询字符串的时候使用的分词器
- analyze_wildcard:通配符或者前缀查询是否被分析,默认为 false
- explain:在每个返回结果中,将包含评分机制的解释
- _source:是否包含元数据,同时支持
_source_includes
和_source_excludes
- lenient:若设置为 true,字段类型转换失败的时候将被忽略,默认为 false
- default_operator:默认多个条件的关系,AND 或者 OR,默认为 OR
- search_type:搜索的类型,可以为
dfs_query_then_fetch
或query_then_fetch
,默认为query_then_fetch
在了解了基本的查询参数后,让我们先来看下什么是指定字段查询和什么是泛查询?
比如 GET /movies/_search?q=2012&df=title
这个例子就是指定字段查询,同样 GET /movies/_search?q=title:2012
也可以达到指定字段查询的目的。
再举一个泛查询的例子 GET /movies/_search?q=2012
,会对所有字段进行查询。
接下来,看下什么是 Term Query 和 Phrase Query:
比如:Beautiful Mind
等效于 Beautiful
OR Mind
;"Beautiful Mind"
等效于 Beautiful
AND Mind
,另外还要求前后顺序保存一致。
当为 Term Query 的时候,就需要把这两个词用括号括起来,请求为 GET /movies/_search?q=title:(Beautiful Mind)
,意思就是查询 title
中包括 Beautiful
或者 Mind
。
当为 Phrase Query 的时候就需要用引号包起来,请求为 GET /movies/_search?q=title:"Beautiful Mind"
。
另外还支持布尔操作,比如 AND(&&)、OR(||)、NOT(!),需要注意大写,不能小写。
在这里举一个 NOT 的例子:GET /movies/_search?q=title:(Beautiful NOT Mind)
,这个请求表示查询 title
中必须包括 Beautiful
不能包括 Mind
的文档。
URI Search 还包括一些范围查询和数学运算符号,比如指定电影的年份大于 1994:GET /movies/_search?q=year:>=1994
。
URI Search 还支持通配符查询(查询效率低,占用内存大,不建议使用,特别是放在前面),还支持正则表达式,以及模糊匹配和近似查询。
URI Search 好处就是操作简单,只要写个 URI 就可以了,方便测试,但是 URI Search 只包含一部分查询语法,不能覆盖所有 ES 支持的查询语法。
因此让我们来看下 Request Body Search:
Request Body Search
在 ES 中一些高阶用法只能在 Request Body 里做,所以我们尽量使用 Request Body Search,它支持 GET 和 POST 方式对索引进行查询,需要指定操作的索引名称,同样也要通过 _search
来标明这个请求为搜索请求,我们可以在请求体中使用 ES 提供的 DSL,下面这个例子就是简单的 Query DSL:
POST /users/_search
{
"query": {
"match_all": {}
}
}
相关文章