基本查询
通过match实现全文搜索
{FIELD} - 就是我们需要匹配的字段名
{TEXT} - 就是我们需要匹配的内容
{
"query": {
"match": {
"{FIELD}": "{TEXT}"
}
}
}
通过term实现精确搜索
{FIELD} - 就是我们需要匹配的字段名
{TEXT} - 就是我们需要匹配的内容
{
"query": {
"term": {
"field": "value"
}
}
}
类似sql
select * from zyzkwjj where field = "value"
通过terms实现SQL的in搜索
{
"query": {
"terms": {
"{FIELD}": [
"{VALUE1}",
"{VALUE2}"
]
}
}
}
{FIELD} - 就是我们需要匹配的字段名
{VALUE1}, {VALUE2} .... {VALUE N} - 就是我们需要匹配的内容,除了TEXT类型字段以外的任意类型。
类似sql
select * from zyzkwjj where field in( "value1","value2"....)
通过range实现范围搜索,类似SQL语句中的>, >=, <, <=表达式
{
"query": {
"range": {
"{FIELD}": {
"gte": value1,
"lte": value2
}
}
}
}
参数说明:
{FIELD} - 字段名
gte范围参数 - 等价于>=
lte范围参数 - 等价于 <=
范围参数可以只写一个,例如:仅保留 "gte": value1, 则代表 FIELD字段 >= value1
范围参数如下:
gt
gte
lt
lte
类似sql
select * from zyzkwjj where field >=value1 and field<=value2
bool组合查询搜索,类似SQL中的and (且)、or (或)语法
{
"query": {
"bool": { // bool查询
"must": [], // must条件,类似SQL中的and, 代表必须匹配条件
"must_not": [], // must_not条件,跟must相反,必须不匹配条件
"should": [] // should条件,类似SQL中or, 代表匹配其中一个条件
}
}
}
参数说明
must条件,类似SQL中的and, 代表必须匹配条件
{
"query": {
"bool": {
"must": [
{匹配条件1},
{匹配条件2},
...可以有N个匹配条件...
]
}
}
}
{
"query": {
"bool": {
"must": [
{
"term": {
"qzh": "001"
}
},
{
"term": {
"ajh": "0001"
}
}
]
}
}
}
类似sql
select * from zyzkwjj where qzh="001" and ajh="0001"
must_not条件,跟must相反,必须不匹配条件
{
"query": {
"bool": {
"must_not": [
{匹配条件1},
{匹配条件2},
...可以有N个匹配条件...
]
}
}
}
{
"query": {
"bool": {
"must_not": [
{
"term": {
"qzh": "001"
}
},
{
"term": {
"ajh": "0001"
}
}
]
}
}
}
类似sql
select * from zyzkwjj where qzh!="001" and ajh!="0001"
should条件,类似SQL中or, 代表匹配其中一个条件
{
"query": {
"bool": {
"should": [
{匹配条件1},
{匹配条件2},
…可以有N个匹配条件…
]
}
}
}
{
"query": {
"bool": {
"should": [
{
"match": {
"qzh": "001"
}
},
{
"match": {
"ajh": "0001"
}
}
]
}
}
}
类似sql
select * from zyzkwjj where qzh="001" or ajh="0001"
bool综合查询
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"qzh": "001"
}
},
{
"range": {
"nd": {
"gte": 2000,
"lte": 2020
}
}
}
]
}
},
{
"terms": {
"ajh": [
"0001",
"0002"
]
}
}
]
}
}
}
select * from zyzkwjj where (qzh='001' and (nd>=2000 and nd<=2020)) or ajh in ("0001","0002")
wildcard模糊匹配,使用时需要加*通配,跟SQL的%类似
{
"query": {
"wildcard": {
"ztm": "*测试*"
}
}
}
查询的字段类型是string类型,对应ES中的text,keyword(这种查询方式会慢,查询不进行分词处理)
match_phrase_prefix模糊匹配SQL的like类似
{
"query": {
"match_phrase_prefix": {
"ztm": "测试"
}
}
}
multi_match (match 查询的升级版,可以指定多个字段查询,也可以添加权重,更倾向于匹配哪个字段)
{
"query": {
"multi_match": {
"query": "测试",
"fields": ["zrz","ztm"]
}
}
}
{
"query": {
"multi_match": {
"query": "测试",
"fields": ["zrz^10","ztm"]
}
}
}
query_string query中可以使用Lucene 查询方式,选择and 、or、not等
{
"query": {
"query_string": {
"default_field": "ztm",
"query": "测试 or 归档"
}
}
}
simple_query_string query_string 的升级,可以直接使用 +、|、- 代替 AND、OR、NOT 等。
{
"query": {
"simple_query_string": {
"default_field": "ztm",
"query": "测试 + 归档"
}
}
}
GEO地理信息查询
ES的地理信息存储的核心是:
坐标点 geo_point(坐标点,经纬度)
geo_bounding_box 在地图上画一个有规则的矩形,搜索被矩形包含的坐标点对应的文档记录。
geo_distance给出一个坐标点和距离,搜索出这个距离范围内的相关文档。
geo_polygon 在地图上画一个不规则的多边形,搜索被多边形包含的坐标点对应的文档
地理形状 geo_shape(点、线、面、圆、椭圆等)
geo_shape以图形的方式存储地理信息(图形就是无数个点组成的,可以是点、线、多边形、圆等)
交集 匹配图形重叠(默认方式)。
不重叠 匹配图形不重叠。
包含 匹配图形包含另外一个图形。
常用的数学几何逻辑查询:
按距离查询(坐标之间的距离,比如打车软件,外面软件,方圆多少公里等需求)
坐标点跟地理形状的包含关系(一个坐标点是否在是同一个点、是否在一条线上、是否在面里)
地理形状的包含关系(线之间的交叉点、面的交集,包含关系)
ES图形存储geo_shape
点point
圆形circle
矩形envelope
多边形 polygon
使用图形必须定义索引字段类型为geo_shape
点point存储
{
"location" : {
"type" : "point",
"coordinates" : [113.41,29.58]
}
}
coordinates数据格式:[经度, 纬度]
圆形circle存储
{
"location" : {
"type" : "circle",
"coordinates" : [113.41,29.58],
"radius" : "2km"
}
}
coordinates数据格式:[经度, 纬度](圆心)。 radius 标注圆形的半径,单位支持 km、m
矩形envelope存储
{
"location" : {
"type" : "envelope",
"coordinates" : {
[113.41,29.58],
[123.41,39.58]
},
}
}
coordinates数据格式:[经度, 纬度] 第一个值是左上角坐标,第二个是右下角坐标
多边形polygon存储
{
"location" : {
"type" : "polygon",
"coordinates" : [
[
[113.41,29.58],
[123.41,39.58],
[133.41,49.58]
......
],
[
[116.41,34.58],
[128.41,45.58],
[130.41,47.58]
......
]
],
}
}
coordinates数据格式:[经度, 纬度] 点坐标,可以有N个,是个多层数组,类似一个多边形漏斗,外轮廓、内轮廓....
地理坐标geo_point(索引创建时指定字段类型为geo_point)
单独进行存储lat 纬度,lon经度
{
"location": {
"lat": 29.58,
"lon": 113.41
}
}
数组存储 遵循 [经度,纬度] 的顺序
{
"location": [113.41,29.58]
}
字符串存储 遵循 纬度,经度
{
"location": "29.58,113.41"
}
距离搜索geo_distance,_geo_distance排序(支持km、m)
以location中的坐标为中心,距离这个坐标点2km之内的点都找出来
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "2km",
"location": {
"lat": 29.58,
"lon": 113.41
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 39.889916,
"lon": 116.379547
},
"order": "asc"
}
}
]
}
distance,标注查询的范围,支持km,m。filter禁掉相关度计算,缓存结果
矩形图形检索geo_bounding_box(地图上画一个矩形图形,查出图形中所包含的所有坐标)
{
"query": {
"bool": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 29.58,
"lon": 113.41
},
"bottom_right": {
"lat": 39.58,
"lon": 123.41
}
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 29.58,
"lon": 113.41
},
"order": "asc"
}
}
]
}
top_left 是矩形左上角坐标,bottom_right 是矩形右下角坐标
多边形图形检索geo_polygon
{
"query": {
"bool": {
"filter": {
"geo_polygon": {
"location": {
"points": [
{
"lat": 29.58,
"lon": 113.41
},
{
"lat": 39.58,
"lon": 123.41
},
{
"lat": 49.58,
"lon": 133.41
}
]
}
}
}
}
}
}
points 是数组,可以标注多个点连成面,形成多边形
通用图形检索
intersects 查询的形状与文档的形状有重叠(默认)。
disjoint - 查询的形状与文档的形状完全不重叠。
within - 查询的形状包含文档的形状。
{
"query": {
"bool": {
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "envelope",
"coordinates": [
[
113.41,
29.58
],
[
117.41,
39.58
]
]
},
"relation": "within"
}
}
}
}
}
}
ES排序
{
"query": {
...查询条件....
},
"sort": [
{
"{Field1}": { // 排序字段1
"order": "desc" // 排序方向,asc或者desc, 升序和降序
}
},
{
"{Field2}": { // 排序字段2
"order": "desc" // 排序方向,asc或者desc, 升序和降序
}
}
....多个排序字段.....
]
}
{
"query": {
"match_all": {}
},
"sort": [
{
"zyzkwjj.nd": { // 嵌套对象,使用 点 连接字段名即可
"order": "desc"
}
}
]
}
{
"query": {
"match_all": {}
},
"sort": [
{
"qzh": {
"order": "desc"
}
},
{
"ajh": {
"order": "asc"
}
}
]
}
类似sql
select * from zyzkwjj order by qzh desc,ajh asc
分组聚合统计(类似sql的group by)
terms类似SQL的group by,根据字段唯一值分组。
histogram根据数值间隔分组,例如: 年龄按10间隔分组,0、10、20、30等等。
date_histogram根据时间间隔分组,例如:按月、按天、按小时分组。
range按数值范围分组,例如: 0-50一组,50-100一组,100-150一组。
桶聚合一般不单独使用,都是配合指标聚合一起使用,对数据分组之后肯定要统计桶内数据,在ES中如果没有明确指定指标聚合,默认使用Value Count指标聚合,统计桶内文档总数。
terms聚合
{
"aggs": {
"qzh_census": { // 聚合查询的名字,随便取个名
"terms": { // 聚合类型为: terms
"field": "qzh" // 根据qzh字段值,分桶
}
}
}
}
{
"query": {
"bool": {
"must_not": [
{
"term": {
"ajh": ""
}
}
]
}
},
"aggs": {
"popular_qzh": {
"terms": {
"size":300,
"field": "qzh"
}
}
}
}
类似sql
select qzh,count(qzh) from zyzkwjj where ajh!="" limit 0,300;
注:must_not 相当于【不等于】,分组聚合统计默认只展示10条数据,可以在terms 中加上size进行分页提取数据。如果在外部添加size 那说明是获取指定的size的值得记录数进行分组统计例如以下示例
{
"query": {
"bool": {
"must_not": [
{
"term": {
"ajh": ""
}
}
]
}
},
"from": 0,
"size": 5000,
"aggs": {
"popular_qzh": {
"terms": {
"size":300,
"field": "qzh"
}
}
}
}
类似sql
select p.qzh,count(p.qzh) from (select qzh from zyzkwjj where ajh!="" limit 0,5000) p group by p.qzh limit 0,300;
histogram聚合(直方图)
{
"aggs" : {
"nds" : { // 聚合查询名字,随便取一个
"histogram" : { // 聚合类型为:histogram
"field" : "nd", // 根据nd字段分桶
"interval" : 2 // 分桶的间隔为2,意思就是nd字段值按2间隔分组
}
}
}
}
date_histogram聚合(直方图)
{
"aggs" : {
"sales_over_time" : { // 聚合查询名字,随便取一个
"date_histogram" : { // 聚合类型为: date_histogram
"field" : "date", // 根据date字段分组
"calendar_interval" : "month", // 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
"format" : "yyyy-MM-dd" // 设置返回结果中桶key的时间格式
}
}
}
}
range聚合
{
"aggs" : {
"nd_ranges" : { // 聚合查询名字,随便取一个
"range" : { // 聚合类型为: range
"field" : "nd", // 根据nd字段分桶
"ranges" : [ // 范围配置
{ "to" : 2010 }, // 意思就是 nd <= 2010的文档归类到一个桶
{ "from" : 2011, "to" : 2015 }, // nd>2011 and nd<2015的文档归类到一个桶
{ "from" : 2015 } // nd>2015的文档归类到一个桶
]
}
}
}
}
指标聚合value_count、max、min、avg、sum等
value Count 类似sql的count函数,统计总数
cardinality 类似SQL的count(DISTINCT 字段), 统计不重复的数据总数
avg 求平均值
sum 求和
max 求最大值
min 求最小值
value_count函数统计文档数量
{
"aggs": {
"value_count_census": { // 聚合查询的名字,随便取个名字
"value_count": { // 聚合类型为:value_count
"field": "qzh" // 统计qzh这个字段值的总条数
}
}
}
}
类似sql
select count(qzh) from zyzkwjj
cardinality函数统计文档数量
{
"aggs": {
"cardinality_census": { // 聚合查询的名字,随便取个名字
"cardinality": { // 聚合类型为:cardinality
"field": "qzh" // 统计qzh这个字段值的总条数
}
}
}
}
类似sql
select count(DISTINCT qzh) from zyzkwjj
注:sql的count是不会丢失精度而ES的cardinality基数聚合统计的总数是一个近似值,会有一定的误差,这么做的目的是为了性能,因为在海量的数据中精确统计总数是非常消耗性能的,所以得出的值是一个近似值。
avg函数统计文档数量
{
"aggs": {
"avg_census": { // 聚合查询的名字,随便取个名字
"avg": { // 聚合类型为:avg
"field": "qzh" // 统计qzh这个字段值的总条数
}
}
}
}
类似sql
select avg(qzh) from zyzkwjj
sum函数统计文档数量
{
"aggs": {
"sum_census": { // 聚合查询的名字,随便取个名字
"sum": { // 聚合类型为:sum
"field": "qzh" // 统计qzh这个字段值的总条数
}
}
}
}
类似sql
select sum(qzh) from zyzkwjj
max函数统计文档数量
{
"aggs": {
"max_census": { // 聚合查询的名字,随便取个名字
"max": { // 聚合类型为:max
"field": "qzh" // 统计qzh这个字段值的总条数
}
}
}
}
类似sql
select max(qzh) from zyzkwjj
min函数统计文档数量
{
"aggs": {
"min_census": { // 聚合查询的名字,随便取个名字
"min": { // 聚合类型为:min
"field": "qzh" // 统计qzh这个字段值的总条数
}
}
}
}
类似sql
select min(qzh) from zyzkwjj
示例
{
"size": 0, // size = 0,代表不想返回query查询结果,只要统计结果
"query": { // 设置query查询条件,后面的aggs统计,仅对query查询结果进行统计
"constant_score": {
"filter": {
"match": {
"nd": "2023"
}
}
}
},
"aggs": { // 统计query查询结果, 默认情况如果不写query语句,则代表统计所有数据
"hat_qzhs": { // 聚合查询名字,计算qzh总和
"sum": {
"field": "qzh"
}
},
"min_qzh": { // 聚合查询名字,计算qzh最小值
"min": {
"field": "qzh"
}
},
"max_qzh": { // 聚合查询名字,计算qzh最大值
"max": {
"field": "qzh"
}
}
}
}