赞
踩
其实准确来说,ES中的查询操作分为2种:
查询(query)
和过滤(filter)
。
查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序
。过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档 。所以,单从性能考虑,过滤比查询更快
。换句话说,过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,
应先使用过滤操作过滤数据, 然后使用查询匹配数据。
// 从所有文档中过滤age>=10的文档 GET /ems/_search { "query": { "bool": { "must": [ {"match_all": {}} ], "filter": { "range": { "age": { "gte": 10 } } } } } }
提示: 在执行filter和query时,
先执行filter在执行query
提示:
Elasticsearch会自动缓存经常使用的过滤器,以加快性能。
// 先过滤出content字段关键词为spring的文档,再query出name为黑的文档 GET /ems/_search { "query": { "bool": { "must": [ { "term": { "name": { "value": "黑" } } } ], "filter": { "term": { "content":"spring" } } } } } // 找到content中过滤不包含 科技,声音的文档, 然后在进行term关键词查询name为中国的文档 GET /dangdang/_search #使用terms过滤 { "query": { "bool": { "must": [ {"term": { "name": { "value": "中国" } }} ], "filter": { "terms": { "content":[ "科技", "声音" ] } } } } }
GET /ems/_search { "query": { "bool": { "must": [ {"term": { "name": { "value": "中国" } }} ], "filter": { "range": { "age": { "gte": 7, "lte": 20 } } } } } }
过滤出存在指定字段的文档
// 首先过滤出存在name字段的文档,并且进行term关键词查询,name字段中包含中国的文档 GET /ems/_search { "query": { "bool": { "must": [ {"term": { "name": { "value": "中国" } }} ], "filter": { "exists": { "field":"name" } } } } }
过滤含有指定字段的索引记录
GET /ems/_search { "query": { "bool": { "must": [ {"term": { "name": { "value": "中国" } }} ], "filter": { "ids": { "values": ["1","2","3"] } } } } }
聚合:英文为Aggregation,是es除搜索功能外提供的针对es数据做统计分析的功能。聚合有助于根据搜索查询提供聚合数据。
聚合查询是数据库中重要的功能特性,ES作为搜索引擎兼数据库,同样提供了强大的聚合分析能力。它基于查询条件来对数据进行分桶、计算的方法。有点类似于 SQL 中的 group by 再加一些函数方法的操作。
注意事项:text类型是不支持聚合的。
// 创建索引 index 和映射 mapping PUT /fruit { "mappings": { "properties": { "title":{ "type": "keyword" }, "price":{ "type":"double" }, "description":{ "type": "text", "analyzer": "ik_max_word" } } } } // 放入测试数据 PUT /fruit/_bulk {"index":{}} {"title" : "面包","price" : 19.9,"description" : "小面包非常好吃"} {"index":{}} {"title" : "旺仔牛奶","price" : 29.9,"description" : "非常好喝"} {"index":{}} {"title" : "日本豆","price" : 19.9,"description" : "日本豆非常好吃"} {"index":{}} {"title" : "小馒头","price" : 19.9,"description" : "小馒头非常好吃"} {"index":{}} {"title" : "大辣片","price" : 39.9,"description" : "大辣片非常好吃"} {"index":{}} {"title" : "透心凉","price" : 9.9,"description" : "透心凉非常好喝"} {"index":{}} {"title" : "小浣熊","price" : 19.9,"description" : "童年的味道"} {"index":{}} {"title" : "海苔","price" : 19.9,"description" : "海的味道"}
// 根据检索条件查询出来的文档, 进行分组;根据price进行分组,分组叫price_group GET /fruit/_search { "query": { "term": { "description": { "value": "吃" } } }, "aggs": { "price_group": { "terms": { "field": "price" } } } }
// 结果 { "took" : 3, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 4, "relation" : "eq" }, "max_score" : 0.6489038, "hits" : [ { "_index" : "fruit", "_type" : "_doc", "_id" : "xbUHXYIBkJ4IdFBIeDXc", "_score" : 0.6489038, "_source" : { "title" : "面包", "price" : 19.9, "description" : "小面包非常好吃" } }, { "_index" : "fruit", "_type" : "_doc", "_id" : "x7UHXYIBkJ4IdFBIeDXc", "_score" : 0.6489038, "_source" : { "title" : "日本豆", "price" : 19.9, "description" : "日本豆非常好吃" } }, { "_index" : "fruit", "_type" : "_doc", "_id" : "yLUHXYIBkJ4IdFBIeDXc", "_score" : 0.6489038, "_source" : { "title" : "小馒头", "price" : 19.9, "description" : "小馒头非常好吃" } }, { "_index" : "fruit", "_type" : "_doc", "_id" : "ybUHXYIBkJ4IdFBIeDXc", "_score" : 0.6489038, "_source" : { "title" : "大辣片", "price" : 39.9, "description" : "大辣片非常好吃" } } ] }, "aggregations" : { "price_group" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : 19.9, "doc_count" : 3 }, { "key" : 39.9, "doc_count" : 1 } ] } } }
# 求最大值
GET /fruit/_search
{
"aggs": {
"price_max": {
"max": {
"field": "price"
}
}
}
}
# 求最小值
GET /fruit/_search
{
"aggs": {
"price_min": {
"min": {
"field": "price"
}
}
}
}
# 求平均值
GET /fruit/_search
{
"aggs": {
"price_agv": {
"avg": {
"field": "price"
}
}
}
}
# 求和
GET /fruit/_search
{
"aggs": {
"price_sum": {
"sum": {
"field": "price"
}
}
}
}
// 求不同价格的数量
@Test
public void testAggsPrice() throws IOException {
SearchRequest searchRequest = new SearchRequest("fruit");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("group_price").field("price"));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
ParsedDoubleTerms terms = aggregations.get("group_price");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (Terms.Bucket bucket : buckets) {
System.out.println(bucket.getKey() + ", "+ bucket.getDocCount());
}
}
// 求不同名称的数量
@Test
public void testAggsTitle() throws IOException {
SearchRequest searchRequest = new SearchRequest("fruit");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("group_title").field("title"));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
ParsedStringTerms terms = aggregations.get("group_title");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (Terms.Bucket bucket : buckets) {
System.out.println(bucket.getKey() + ", "+ bucket.getDocCount());
}
}
// 求和
@Test
public void testAggsSum() throws IOException {
SearchRequest searchRequest = new SearchRequest("fruit");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.sum("sum_price").field("price"));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
ParsedSum parsedSum = searchResponse.getAggregations().get("sum_price");
System.out.println(parsedSum.getValue());
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。