ElasticSearch-深入理解系列8-高级查询

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": {}
}
返回所有结果


你可能感兴趣的:(elasticsearch)