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

来源:互联网 发布:用递归算法计算斐波拉 编辑:程序博客网 时间:2024/05/21 04:41
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
} },
... 9RESULTS 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 termrange子句用于过滤器上下文。他们会过滤掉不符合的文件,但不会影响匹配文件的分数。
13.4
GET /silver_wechat*/_search
{
"query": {}
}
返回结果为空。没有查询条件及没有查询内容

GET /silver_wechat*/_search
{
"filter": {}
}
返回所有结果


原创粉丝点击