-
Notifications
You must be signed in to change notification settings - Fork 61
elasticsearch query toolkit help doc
## 搜索请求SQL结构
SELECT [fields] FROM [index.type] QUERY [score query condition] WHERE [bool query condition] ORDER BY [sort field] LIMIT [0, 10]
## 聚合查询SQL结构
SELECT [MIN(field),MAX(field),SUM(field),AVG(field)] from [index.type] QUERY [score query condition] WHERE [bool query condition] GROUP BY [agg methods]
以上两种SQL结构分别对应ES的搜索请求和聚合请求,下面大概看看这两种结构,后续会详细介绍。 1、搜索请求SQL
- SELECT项,可以是通配符
*
也可以是具体指定需要返回的字段(针对inner/nested文档直接通过.
引用) - FROM项,后面跟的是索引名和文档类型如:product.car 表示查询product这个索引下的car类型
- QUERY项,关键字QUERY和WHERE是同级的,不同之处是QUERY后面跟的查询条件会进行
打分
- WHERE项,和QUERY同级,后面跟的查询条件不会参与打分,只是进行简单的
bool匹配
- ORDER BY项,跟SQL一样后面跟排序条件
- LIMIT 项,指定分页参数对应ES的from,size参数
2、 聚合请求SQL
- SELECT/FROM/QUERY/WHERE 项同上
- GROUP BY项,后面跟的是需要分组查询的条件,如前支持只支持:terms、range
为了能更好的说明SQL语法的使用,我们假设已经存在一个名叫product
的索引,索引下有一个apple
的类型,具体的mapping像下面这样,其中provider是一个inner doc表示供应商,buyers是一个nested doc表示购买者。
"mappings": {
"apple": {
"properties": {
"productName": {
"type": "string",
"index": "not_analyzed"
},
"productCode": {
"type": "string",
"index": "not_analyzed"
},
"minPrice": {
"type": "double"
},
"advicePrice": {
"type": "double"
},
"provider": {
"type": "object",
"properties": {
"providerName": {
"type": "string",
"index": "not_analyzed"
},
"providerLevel" : {
"type": "integer"
}
}
},
"buyers": {
"type": "nested",
"properties": {
"buyerName": {
"type": "string",
"index": "not_analyzed"
},
"productPrice": {
"type": "double"
}
}
}
}
}
}
注意:由于Inner Doc和Root Doc的对应关系是一对一,Nested Doc和Root Doc的对应关系是多对一,所以为了区分这种关系在引用Nesetd Doc时需要在类型前加上 $ 符号,如:$buyers.buyerName(Nested Doc引用需要加 $ 符号),provider.privideName(Inner Doc直接引用)
# 支持通配符
SELECT * FROM product.apple
# 指定具体返回的字段
SELECT productName,productCode FROM product.apple
# 对Inner Doc字段的引用直接通过 “.”
SELECT provider.providerName FROM product.apple
# 当然也可对Inner Doc字段通配
SELECT productName,provider.* FROM product.apple
# 对于Nested Doc的引用需要需要在类型名前加上 “$”
SELECT $buyers.buyerName FROM product.apple
在SQL中WHERE项后面指定的是bool条件,不会参与打分,这些条件最终会被放到bool query
中的filter
中提交给ES指定
SELECT * FROM product.apple WHERE minPrice >= 100 and minPrice <= 200
SELECT * FROM product.apple WHERE minPrice BETWEEN 100 AND 200
SELECT * FROM product.apple WHERE provider.providerLevel in (1, 2, 3) and provider.providerLevel not in (4, 5)
SELECT * FROM product.apple WHERE productName is not null and productCode is null
注意:上面SQL中WHERE
可以完全替换成QUERY
返回的结果一模一样,唯一不同的是QUERY
会计算得分,WHERE
只是单纯的bool匹配
我们都知道在针对nested doc做查询时有专门的nest查询语法,且必须指定一个nested_path才能将多个子查询放到同一个nested query context中,在使用SQL对nested doc查询时不需要显示指定某个或多个条件是存在同一个context中,程序会自动识别,看下面例子:
两个条件同级都是针对内嵌文档的,会被识别存在于同一个neste context里
SELECT * FROM product.apple WHERE $buyers.buyerName = 'usa' and $buyers.productPrice < 200
{
"query" : {
"bool" : {
"filter" : {
"bool" : {
"must" : {
"nested" : {
"query" : {
"bool" : {
"must" : [ {
"term" : {
"buyers.buyerName" : "usa"
}
}, {
"range" : {
"buyers.productPrice" : {
"from" : null,
"to" : 200,
"include_lower" : true,
"include_upper" : false
}
}
} ]
}
},
"path" : "buyers"
}
}
}
}
}
}
}
两个内嵌条件不同级放到不同nested context里面
SELECT * FROM product.apple WHERE ($buyers.buyerName = 'usa' or minPrice > 100) and $buyers.productPrice < 200
{
"query" : {
"bool" : {
"filter" : {
"bool" : {
"must" : [ {
"bool" : {
"should" : [ {
"range" : {
"minPrice" : {
"from" : 100,
"to" : null,
"include_lower" : false,
"include_upper" : true
}
}
}, {
"nested" : {
"query" : {
"term" : {
"buyers.buyerName" : "usa"
}
},
"path" : "buyers"
}
} ]
}
}, {
"nested" : {
"query" : {
"range" : {
"buyers.productPrice" : {
"from" : null,
"to" : 200,
"include_lower" : true,
"include_upper" : false
}
}
},
"path" : "buyers"
}
} ]
}
}
}
}
}
SELECT * FROM product.apple WHERE provider.providerLevel in (1, 2, 3)
SELECT * FROM product.apple WHERE provider.providerName = 'usa'
# 在WHERE条件中指定仅仅作为bool查询
SELECT * FROM product.apple WHERE term(productName, 'iphone6s')
{
"query" : {
"bool" : {
"filter" : {
"bool" : {
"must" : {
"term" : {
"productName" : "iphone6s"
}
}
}
}
}
}
}
# 在QUERY条件中指定根据文档打分排序,并能指定可选参数, 指定权重
SELECT * FROM product.apple QUERY term(productName, 'iphone6s', 'boost:2.0f')
{
"query" : {
"bool" : {
"must" : {
"term" : {
"productName" : {
"value" : "iphone6s",
"boost" : 2.0
}
}
}
}
}
}
注意1:这里的可选参数是一个以key:value组成的键值对,多个键值对之间用逗号隔开 注意2:terms查询和term类似,这里不再赘述 注意3:term查询其实和SQL中的 “=” 操作一样
SELECT * FROM product.apple QUERY match(productName, 'iphone6s', 'boost:2.0f,type:boolean,operator:or,minimum_should_match:75%') WHERE minPrice > 100
{
"query" : {
"bool" : {
"must" : {
"match" : {
"productName" : {
"query" : "iphone6s",
"type" : "boolean",
"operator" : "OR",
"boost" : 2.0,
"minimum_should_match" : "75%"
}
}
},
"filter" : {
"bool" : {
"must" : {
"range" : {
"minPrice" : {
"from" : 100,
"to" : null,
"include_lower" : false,
"include_upper" : true
}
}
}
}
}
}
}
}
注意1:这里使用了QUERY和WHERE两种条件配合使用, WHERE达到过滤的效果, QUERY在过滤结果基础上再进行match匹配 注意2: match查询所有的可选参数请参看官网的参数说明:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-match-query.html 注意3:match查询支持多个函数名:match、match_query、matchQuery
SELECT * FROM product.apple QUERY multiMatch('productName^3, productCode', 'iphone6s') WHERE minPrice > 100
{
"query" : {
"bool" : {
"must" : {
"multi_match" : {
"query" : "iphone6s",
"fields" : [ "productName^3", " productCode" ]
}
},
"filter" : {
"bool" : {
"must" : {
"range" : {
"minPrice" : {
"from" : 100,
"to" : null,
"include_lower" : false,
"include_upper" : true
}
}
}
}
}
}
}
}
SELECT * FROM product.apple QUERY WHERE minPrice > 100
作者: [@陈楠] Email: 465360798@qq.com