简易搜索
简单搜索是通过查询字符串定义的,查询方式简单,但实现的功能也比较少。
空搜索
GET /_search
响应内容如下
- total:匹配到的文档总数
- _score:相关性得分,衡量了文档与查询的匹配程度
- max_score:指的是所有文档匹配查询中_score的最大值
- took:整个搜索请求话费的毫秒数
- shards:参与查询的分片数
- suffessfull:成功的次数
timeout:查询是否超时,查询时可以设置超时时间
GET /_search?timeout=10ms
搜索特定文档
搜索全部文档的请求,默认返回前10个命中的结果
GET /megacorp/employee/_search?pretty}}}
- 带关键字的查询q=属性:
的查询,可以得到所有属性=value的结果
GET /megacorp/employee/_search?q=last_name:Smith
通过URL路径的方式限定查询的索引和类型范围
例:在索引gb和us的所有类型中搜索
/gb,us/_search
例:在以g或u开头的索引的所有类型中搜索
/g*,u*/_search
例:在索引gb和us的类型为user和tweet中搜索
/_all/user,tweet/_search
每次查询结果都是排序的,但一个搜索请求常常设计多个分片,每个分片生成自己排好序的结果,它们接着需要集中起来排序以确保整体排序正确。
查询所有类型为tweet并在tweet字段中包含elasticsearch字符的文档
GET /_all/tweet/_search?q=tweet:elasticsearch
如果查找name字段中包含”john“和tweet字段中包含”mary“的结果,实际的查询结果只需要变为如下:
GET /a_ll/tweet/_search?q=tweet:elasticseach+name:john+tweet:mary
校验查询语句
查询语句可以变的非常复杂,所以我们需要使用validate方法校验查询语句。
GET /gb/tweet/_validate/query
{
"query":{
"tweet": {
"match":"really powerfull"
}
}
}
如果是合法语句,会有一个explainations字段为每一个索引索引一段描述,每个索引会有不同的映射关系和分析器:
pretty
在查询url中最后添加上pretty参数,可以使结果非常整洁
get http://10.214.208.166:9200/wiforce-2015.12.20
/_mapping/detected_ap_measurement?pretty
富搜索–结构化查询语句DSL
大多数的参数以JSON格式所容纳而非查询字符串,请求体查询并不仅仅用来处理查询,而且还可以高亮返回结果中的片段,并且给出帮助你的用户找寻最好的结果的相关数据建议。
指定索引和类型
GET /index/type1,type2/_search
{}
当然我们还可以使用from和size参数进行分页
GET /_search
{
"from":30,
"size":10
}
查询关键字
query:查询关键字
filter: 需要以过滤条件开始,把query语句放到filtered中
在收件箱中查询email中与business opportunity相关的邮件。查询语句为:
GET /_search
{
"query":{
"filtered":{
"filter": {"term": {"folder": "inbox"} }
}
}
}
term:主要用于精确匹配哪些值,比如数字,日期,布尔值(not_analyzed的字符串)
{"term": {"age": 26 }}
terms:允许多个匹配
{"terms": {"age": [26,1,2,3,4] }}
match_all:匹配所有的文档
match: 查询子句用来更进一步匹配,match的匹配并不是完全匹配,例如tweet中包含elasticsearch字段的
GET /_search { "query":{ "match":{ "tweet":"elasticsearch" } }
bool: 用于合并多个查询子句
- must: 必须符合的子句,多个查询条件的完全匹配and
- must_not: 不需要符合的子句,多个查询条件的相反匹配 not
should:至少有一个查询条件匹配,相当于or,可以有多个
{ "bool":{ "must": {"match": {"tweet": "elasticseach"}}, "must_not": {"match": {"name": "mary"}}, "should": [ {"term": {"starred":true}}, {"term": {"unread":true}} ] } }
range:过滤一定范围内的数据(gt 大于,gte 大于等于, lt 小于, lte小于等于)
range { field :{ gte: value1 lt:value2 } }
- exists,missing:查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件
multi_match查询:允许在做match查询的基础上同时查询多个字段,如要在tilte和body中同时检索关键字“full text search”,则可使用mutli_match检索
{ "multi_match":{ "query": "full text search", "fields": ["title", "body"] } }
聚合查询 aggregations
聚合查询本想放到查询关键字中,但这部分确实会复杂很大,需要用更多的例子描述,所以这里我们单独例一个章节描述,同样以查询关键字为索引。 聚合查询和sql中的 group by 很类似,不同的是elasticseach中的聚合查询非常快,大部分查询都能在1s内完成,这对于mysql这样的传统数据库和基于MR的HIVE是不大可能实现的。
类型
- metric 聚合查询的条件,一般是查询函数
- buckets 聚合查询得到的结果保留到这个字段中
- pipeline 聚合查询可以不断嵌套,深入下去
结构
聚合查询的基本结构如下,与DSL的查询结构类似,同样使用JSON结构体用于描述查询请求。
"aggregations(关键字)" : {
"<aggregation_name(给聚合取个名称)>" : {
"<aggregation_type(聚合类型,sum avg等等)>" : {
<aggregation_body>
}
[,"meta" : { [<meta_data_body>] } ]?
[,"aggregations" : { [<sub_aggregation子聚合>]+ } ]?
}
[,"<aggregation_name_2 平行聚合>" : { ... } ]*
}
metric 聚合
metric(度量)聚合通常是常用的数学函数查询,因此我们会专挑一些有代表性的进行描述
sum 对某个字段求和
{ "aggs" : { "intraday_return" : { "sum" : { "field" : "change" } } } }
avg 计算所有分数的平均值,缺失值用0填充
{ "aggs" : { "avg_grade" : { "avg" : { "field" : "grade" , "missing":0} } } }
返回结果为
{ ... "aggregations": { "avg_grade": { "value": 75 } } }
通常我们需要计算一些合成的字段的平均值,此时就需要在查询体中写脚本完成,例如我们要计算两门课的平均分。
{
"aggs" : {
"avg_grade" : { "avg" : { "script" : "(doc['grade1'].value + doc['grade2'].value)" } }
}
}
stats 常用统计查询
{ "aggs" : { "grades_stats" : { "stats" : { "field" : "grade" } } } }
返回结果
{
...
"aggregations": {
"grades_stats": {
"count": 6,
"min": 60,
"max": 98,
"avg": 78.5,
"sum": 471
}
}
}
extended stats 拓展的统计查询
{ "aggs" : { "grades_stats" : { "stats" : { "field" : "grade" } } } }
返回结果
{
...
"aggregations": {
"grade_stats": {
"count": 9,
"min": 72,
"max": 99,
"avg": 86,
"sum": 774,
"sum_of_squares": 67028,
"variance": 51.55555555555556,
"std_deviation": 7.180219742846005,
"std_deviation_bounds": {
"upper": 100.36043948569201,
"lower": 71.63956051430799
}
}
}
}
min
{ "aggs" : { "min_price" : { "min" : { "field" : "price" } } } }
max
{ "aggs" : { "max_price" : { "max" : { "field" : "price" } } } }
percentile
cardinality(unique count),因为unique方法需要用到一个缓存做分布式的计算,对于海量的数据而言,如果要做到精确的unique count,缓存很容易爆掉。所以ES官方对这个值做了个限制,可以设为threshold为1000,基本上已经能保持一个比较低的错误率。 cardinality的计算使用到了算法
HyperLogLog++top hits 查询最相关的TOP N个结果
{ "aggs": { "top-tags": { "terms": { "field": "tags", "size": 3 }, "aggs": { "top_tag_hits": { "top_hits": { "sort": [ { "last_activity_date": { "order": "desc" } } ], "_source": { "include": [ "title" ] }, "size" : 1 } } } } } }
count 计算值的总和
{ "aggs" : { "grades_count" : { "value_count" : { "field" : "grade" } } } }
接下来的bucket聚合会更复杂,所以我们还是单独用一个章节来讲。