Elasticsearch 查询 DSL 基础入门

撰写于 2017年11月11日 修改于 2017年11月21日 分类 编程杂记 标签 Elasticsearch

虽然使用简单的 GET 参数也可以从 Elasticsearch 获取数据,但要使用强大的查询和聚合功能,查询 DSL (Query Domain Special Language)是必不可少的,这也是官方推荐在生产环境中使用的数据获取方式。DSL 是 RESTful 风格的,并且在 GET 请求中像 POST 一样发送请求体,这点可能与既往经验有点不一样,有些语言和库甚至是不支持 GET 请求中包含请求体的,但在 IETF 的 HTTP/1.1 标准中,并没有说明这一点。好在 JavaScript 是支持的。而且对于 GET 发送的请求,用 POST 方式也可以得到同样的结果。

虽然 curl 或者 Postman 之类都可以组织 RESTFul 请求,不过对于 Elasticsearch 来讲,最方便的还是 Kibana 的 Dev Tools ,可以将搜索历史保存在 localStorage 中,还带有强大的自动完成和语法检查功能。

基础数据

这里准备了 499 条测试数据,下载之后,直接复制全部内容,进入到 Dev Tools ,再放在 POST /_bulk 之后执行,便可以导入数据。index 名为 accesslog-2017.11,type 为 visit ,数据内容是一些访问记录,包括 ip 地址、Useragent、页面的 GET 参数等。下面所有的查询,全部基于这些数据。

常规查询

返回所有结果

使用 SQL 如果不限制获取的数据的起始位置和数量,会直接获取全部,但 Elasticsearch 只会获取前 10 条。比如:

1
SELECT * FROM `test_table`;

这会获取整个表。DSL 里类似的语句是:

1
2
3
4
5
6
GET /accesslog-2017.11/visit/_search
{
"query": {
"match_all": {}
}
}

其它还有个 match_none ,作用与它正好相反——一个文档也没有。

翻页

SQL 里使用 LIMIT 实现翻页,DSL 中使用 from 指定开始位置,size 为获取数量:

1
2
3
4
5
GET /accesslog-2017.11/visit/_search
{
"size": 1,
"from": 10
}

指定返回字段

默认情况下,Elasticsearch 会返回所有的字段,也可以指定需要返回的字段:

1
2
3
4
GET /accesslog-2017.11/visit/_search
{
"_source": ["ip", "ipInfo.province", "urlParams.*"]
}

搜索所有字段

比如,想查询所有字段,是否包含“中”这个字,可以使用 query_string

1
2
3
4
5
6
7
8
GET /accesslog-2017.11/visit/_search
{
"query": {
"query_string": {
"query": "中"
}
}
}

可以使用 "default_field": "ipInfo.country", 指定搜索 ipInfo.country 字段,不过这样得话,不如使用专门针对字段的匹配功能。

一次请求执行多个搜索

_msearch 接口可以一次性处理多个搜索。在搜索体中,每个搜索要占两行,一行指定索引和类型,一行是搜索条件。例如:

1
2
3
4
5
GET /accesslog-2017.11/_msearch
{}
{"query": {"match_all": {}}}
{"index": "accesslog-2017.11", "type": "visit"}
{"query": {"query_string": {"default_field": "ipInfo.province", "query": "宁夏"}}}

返回结果组织在一个名为 responses 的数组中,按照条件的先后顺序排列。

计数

SQL 里使用 COUNT() 计算行数,DSL 提供了 _count 接口计算文档的数量:

1
2
3
4
5
6
GET /accesslog-2017.11/visit/_count
{
"query": {
"match_all": {}
}
}

返回结果中的 count 字段为符合条件的文档数量。

Site by Stiekel using Hexo & Random
© 2010 - 2018

不可能不确定的博主是一名程序员。

Hide