您的位置:首页 > 其它

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

2017-08-20 22:29 387 查看
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=10ms

}

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": {}
}
返回所有结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息