1 查询类型
1.1 根据ID直接查询文档 :GET /index/type/id .类似sql :select * from where tablename=id
1.2 空查询。Get /_search .类似select * from tablename.返回结果格式:
{
"hits"
: {
"total"
:
14
, //结果数量
"hits"
: [ //返回结果,默认只返回
前10条数据
{
"_index"
:
"us"
,
"_type"
:
"tweet"
,
"_id"
:
"7"
,
"_score"
:
1
,
"_source"
: {
"date"
:
"2014-09-17"
,
"name"
:
"John Smith"
,
"tweet"
:
"The Query DSL is really powerful and flexible"
,
"user_id"
:
2
} },
...
9
RESULTS REMOVED ... ],
"max_score"
:
1
},
"took"
:
4
,
"_shards"
: {#参数查询的分片,有多少成功,失败,总数
"failed"
:
0
,
"successful"
:
10
,
"total"
:
10
},
"timed_out"
:
false #是否超时,查询时可以设置:
GET /_search?timeout=
10
ms
}
timed_out:超时后,在后台还会继续执行。紧紧只是为了顺利返回结果。
1.3 多索引、多类别查询。
/gb,us/user,tweet/_search
包括所有索引多个类别:/_all/user,tweet/_search。
搜索一个索引5个主分片和5个索引各1个分片事实上是一样。
2 分页。
2.1 ES接受分页参数是size和from。
size
: 结果返回数量,默认10
from
: 跳过开始的结果数,默认0.
当size=10,from=0时,返回的结果从1到10.
2.2 请求中增加参数
GET /_search?size=
5
&from=
5
或者
GET /silver_wechat*/te_wechat_type/_search
{
"size": 20
, "from": 0
}
2.3 深度分页。
1)深度分页的问题
所以默认每个搜索条件情况下,默认都只能返回10000条数据。
2.4 scroll搜索-搜索10000以后的数据。
3 搜索API支持搜索类型:简易搜索和DSL
3.1 简易搜索:直接将查询字符串放在参数中。比如
GET /_all/tweet/_search?q=tweet:elasticsearch
a)注:_all字段
当检索一个文档时,ES把所有的字符串字段值连接起来放在同一个大字符串中,它被索引为一个特殊的字段_all。比如检索如下文档时,
{
"tweet"
:
"However did I manage before Elasticsearch?"
,
"date"
:
"2014-09-14"
,
"name"
:
"Mary Jones"
,
"user_id"
:
1
}
会拼接成如下的一个字符串:
“However did I manage before Elasticsearch? 2014-09-14 Mary Jones 1"
即_all会查询所有字段。
b)
DSL搜索:将查询的语句构造成JSON字符串。
4 确切值(exact value)和全文文本(fulltext)
在ES中String分为分为确切值和全文文本。
确切之查询比全文文本搜索要容易,只有两种结果,要么匹配要么不匹配。
4.1 确切值
确切值即是确定的,比如Hello和hello是两个不同的值。
4.2 全文本搜索
使用倒排索引来加速搜索。
为了创建倒排索引,ES会将文档中字段值切分成单独的单词(terms or tokens),然后用这些单词建立倒排索引。
5 结构化查询
结构化查询,不仅仅可以用来查询,还可以高亮显示返回结果,
5.1 空查询
GET /_search {
"query"
: {
"match_all"
: {}
} }
相当于
GET /_search
{
}
5。2 查询字句。
结构:
{
QUERY_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,... }
}
或者针对某个字段
{
QUERY_NAME: {
FIELD_NAME: { ARGUMENT: VALUE, ARGUMENT: VALUE,...
} }
}
5.3 多个子句查询
{
"bool"
: {
"must"
: {
"match"
: {
"tweet"
:
"elasticsearch"
}},
"must_not"
: {
"match"
: {
"name"
:
"mary"
}},
"should"
: {
"match"
: {
"tweet"
:
"full text"
}}
} }
复合子句可以相互嵌套,从而实现复杂查询。
6 过滤和查询
结构化查询语句分为两种:结构化查询(Query DSL)和结构化过滤(Filter DSL)
6.1 过滤语句一般只关心文档中某个值
是否包含
特点值.使用
filter
关键字
比如创建时间created是否在2013到2014年
6.2 查询语句一般关心文档中字段值与特定值
匹配程度。适用query关键字。
所以过滤语句得到结果集,而查询语句除了查询匹配的文档,还要计算文档相关性,所以查询语句比过滤语句更好耗时。
6.3 使用场景
查询语句主要做全文搜或者其他进行相关性评分的时候,剩下的可以全部用过滤语句。
6.4 查询语句和过滤语句还可以相关嵌套
7 查询过滤语句
7.1 term过滤
7.2 terms过滤
7.3 range范围查询
gt
-大于
gte
大于等于
lt
小于
lte
小于等于
7.4 Exists和missing,查询文档包含或者不包含某个字段值,类似 SQL的is null
7.5 bool过滤
7.6 match_all查询。查询所有文档,是没有查询条件的默认句
7.7 match查询。match在全文本查询和精确值查询都适用。match查询之前会用分析器先分析一下查询的字符串。
7.8 multi_match。在查询的基础上同时搜索多个字段。
7.9
8 验证DSL查询语句
8.1 使用
validate API
GET /gb/tweet/_validate/query {
"query"
: {
"tweet"
: {
"match"
:
"really powerful"
}
} }
8.2 想要知道更多的非法信息,可以加上
explain参数。
9 深度分页
9.1 查询数量超过10000条时需要使用scroll。
POST
/
twitter
/
tweet
/
_search
?
scroll
=
1m
{
"size"
:
100
,
"query"
:
{
"match"
:
{
"title"
:
"elasticsearch"
}
}
}
查询结果会返回一个参数:_scroll_id。用于下一次获取数据
POST
/
_search
/
scroll #不需要再指定index和type。
{
"scroll"
:
"1m"
,
"scroll_id"
:
"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
只能使用最近的scroll_id.
10 null值处理
10.1 exist过滤器
GET /my_index/posts/_search {
"query" : { "filtered" : {
"filter" : {
"exists" : { "field" : "tags"}}}}}
10.2
missing过滤器
GET /my_index/posts/_search {
"query" : { "filtered" : {
"filter": {
"missing" : { "field" : "tags" }
} }
} }
11 过滤顺序
11.1 条件B匹配1000w个文档,条件B匹配100个文档,B需要在A前面
11.2 过滤条件也会被缓存。比如我们需要之前近一个小时的内容,每次使用下面查询条件
{"query" : { "filtered" : {
"filter" : { "range" : {
"timestamp" : { "gt" : "now-1h"
}}}}
这样的条件不会做缓存。我们可以在这个条件之前加一个包含固定时间的过滤器,先排除大量数据比如增加昨天凌晨的时间筛选。
"bool": { "must": [
{ "range" : { "timestamp" : {
"gt" : "now-1h/d" <1> } 这一个会被缓存。
}},
{ "range" : {
"timestamp" : {
"gt" : "now-1h" <2>
} }}
] }
12 query和filter
12.1 query返回的结果是,文档是否匹配及匹配程度。
filter返回的结果是,匹配查询,不关心匹配程度。
12.2 query返回的结果_score评分一般都不一样(大于1或者小于1)
filter返回的结果的_score评分都是1
13.3 ES也会缓存filter过滤器内容。
{
"query" : { "filtered" : { "query" : { "term" : { "name" : "joe" } }, "filter" : { "term" : { "year" : 1981 } } } }}
这样的查询,会将year=1981的结果缓存起来。
GET
/
_search
{
“query”
:{
“bool”
:{
“must”
:[ {
“match”
:{
“title”
:
“Search”
}},
{
“match”
:{
“content”
:
“Elasticsearch”
}}
],
“filter”
:[
{
“term”
:{
“status”
:
“published”
}},
{
“range”
:{
“publish_date”
:{
“gte”
:
“2015-01-01”
}}}
] } } }
the
term
和
range
子句用于过滤器上下文。他们会过滤掉不符合的文件,但不会影响匹配文件的分数。
13.4
GET /silver_wechat*/_search
{
"query": {}
}
返回结果为空。没有查询条件及没有查询内容
GET /silver_wechat*/_search
{
"filter": {}
}
返回所有结果