ElasticSearch学习-查询

ElasticSearch 用的最多的地是他的查询,统计,还有就是地理信息这块。在项目中我用的到的比较多的是查询和统计。

目录

Match 匹配查询

布尔查询 match

短语查询 match_phrase

 

短语前缀查询 match_phrase_prefix

Term  精确查询

排序

分页查询

条件查询 

统计

时间统计

数值统计


查询关键字:

  • term  精确查询   
  • match 匹配查询

Match 匹配查询

match查询属于全文查询,它会首先分析查询字符串,根据字符串的分词构建查询,最终返回查询结果。

匹配查询一共包括三种类型:

  • 布尔(默认)
  • 短语
  • 前缀

布尔查询 match

对字符串进行分词,将满足分词的文档查询出来,举例:

{  
   "query":{  
      "match":{  
         "eventname":"azure aws cloud"
      }
   }
}

eventname是字段名,此字段可以匹配包含azure,aws或者cloud的文档。 

 match 还有两个查询参数,用于设定匹配条件。

  • operator
  • minimum_should_match
{  
   "query":{  
      "match":{  
         "eventname":{  
            "query":"azure aws cloud security",
            "operator":"or",
            "minimum_should_match":2
         }
      }
   }
}

operator可以为or或者and  or代表满足任意一个分词结果  and 代表同时包括所有的分词结果。

minimus_should_match指定operator为or时,最少匹配的数量。

以上示例代表,只要文档至少包含[azure,aws,cloud,security] 中的2个 就可以完成匹配。

MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("字段名称","字段值");
        matchQueryBuilder.operator(Operator.AND);
        matchQueryBuilder.minimumShouldMatch("2");

 

短语查询 match_phrase

对字符串进行分词,从分析后的文本中构建短语。意思就是必须匹配短语中的所有分词且要保证各个分词位置不变。举例

{  
   "query":{  
      "match_phrase":{  
         "eventname":"Open Source"
      }
   }
}

 

短语前缀查询 match_phrase_prefix

短语前缀查询和短语查询几乎一样,区别在于,短语前缀查询的最后一个分词,做了前缀匹配。

{  
   "query":{  
      "match_phrase_prefix":{  
         "eventname":{  
            "query":"Open Source hac",
            "max_expansions":50
         }
      }
   }
}

 以上示例,匹配的文档例如:[Open Source Hack Night,Open Source Hack GOD]

max_expansions 控制参数默认是50,代表的是通配符数目

Term  精确查询

精确查询 term和match查询不同,它不会关联分数,不会走分词分析。他会精确匹配短语,适用的字段为keyword fields, or in numeric or date fields

{
  "query": {
    "term": {
      "exact_value": "Quick Foxes!" 
    }
  }
}

精确匹配 exact_value值为quick foxes!的 

 Term匹配和Match匹配,查询结果对比:

1.构造实例

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "full_text": {
          "type":  "text" 
        },
        "exact_value": {
          "type":  "keyword" 
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "full_text":   "Quick Foxes!", 
  "exact_value": "Quick Foxes!"  
}

2.构造查询

GET my_index/_search
{
  "query": {
    "term": {
      "exact_value": "Quick Foxes!" 
    }
  }
}

GET my_index/_search
{
  "query": {
    "term": {
      "full_text": "Quick Foxes!" 
    }
  }
}

GET my_index/_search
{
  "query": {
    "term": {
      "full_text": "foxes" 
    }
  }
}

GET my_index/_search
{
  "query": {
    "match": {
      "full_text": "Quick Foxes!" 
    }
  }
}

1.可以精确查找到exact_value 值为Quick Foxes!的。

2.匹配不到,因为full_text不是关键字类型。

3.可以匹配到full_text分词后包含foxes的。

4.可以匹配至少包含[quick,foxes]中其一的。

 

排序

根据年龄 日期  es字段(_score)进行排序

{
    "sort": [
        {
            "date": "desc"
        }, 
        {
            "age": "desc"
        }, 
        "_score"
    ], 
    "query": {
        "term": {
            "name": "李四"
        }
    }
}
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        SortBuilder sortBuilder = SortBuilders.fieldSort("字段名称").order(SortOrder.DESC);
        searchSourceBuilder.sort(sortBuilder);

 

分页查询

{

  "from":0,
  "size":10,
  "query": {
    "match": {
      "full_text": "Quick Foxes!" 
    }
  }
}

分页查询三种方式的优缺点

分页方式说明优点缺点使用场景
from+size假设现在你要查询第100页的10条数据,但是对于es来说,from=1000000,size=100,这时 es需要从各个分片上查询出来10000100条数据,然后汇总计算后从其中取出100条。如果有5个分片则需要查询出来5*10000100条数据。灵活性好,使用简单内存消耗大数据量小

scroll

scroll查询原理是在第一次查询的时候一次性生成一个快照,根据上一次的查询的id来进行下一次的查询,这个就类似于关系型数据库的游标,然后每次滑动都是根据产生的游标id进行下一次查询,这种性能比上面说的分页性能要高出很多,基本都是毫秒级的。 注意:scroll不支持跳页查询。 效率高, 对实时性要求不高的查询,例如微博或者头条滚动查询。报表导出


条件查询 

条件查询需要配合 match和term结合使用

  • fiflter  会缓存结果,不会关联分数
  • must/must_not 不会缓存结果,会关联分数(分数指文档的匹配度,分数越高 越匹配)

简单举例:

{
  "query": { 
    "bool": { @1
      "must": [@2
        { "match": { "title":   "Search"        }},
        { "match": { "content": "Elasticsearch" }}
      ],
      "filter": [ @3
        { "term":  { "status": "published" }},
        { "range": { "publish_date": { "gte": "2015-01-01" }}}
      ]
    }
  }
}

@2 使用query context,意味着他们会返回score来表达匹配结果

@3 使用fiflter context,  意味着会过滤不匹配的文档

fiflter和range的结合,可以用来做范围查询,比如时间或者数值大小

 

统计

在实际项目中,主要应用到的是日期统计。比如统计每个月接口的成功数量,失败数量。

也有其他的统计维度,比如统计接口出错的Top10。等等

6.8版本 统计查询

时间统计

POST /sales/_search?size=0  //size 0  不返回文档内容 只显示统计结果
{
    "aggs" : {
        "sales_over_time" : {//这个统计自己起的名字
            "date_histogram" : {//使用date_histogram关键字
                "field" : "date",//参数
                "interval" : "1M",//时间维度
                "format" : "yyyy-MM-dd" //格式化
            }
        }
    }
}

Response:

{
    ...
    "aggregations": {
        "sales_over_time": {
            "buckets": [
                {
                    "key_as_string": "2015-01-01",
                    "key": 1420070400000,
                    "doc_count": 3
                },
                {
                    "key_as_string": "2015-02-01",
                    "key": 1422748800000,
                    "doc_count": 2
                },
                {
                    "key_as_string": "2015-03-01",
                    "key": 1425168000000,
                    "doc_count": 2
                }
            ]
        }
    }
}

Java 代码: 

DateHistogramAggregationBuilder dateBuilder = AggregationBuilders.dateHistogram("sales_over_time").field("date").format("yyyy-MM-dd").dateHistogramInterval(DateHistogramInterval.DAY);
        //指定根据key(日期)进行排序
        dateBuilder.order(BucketOrder.key(true));

数值统计

举例:统计衬衫的平均值

POST /sales/_search?size=0
{
    "aggs" : {
        "t_shirts" : {//第一层 衬衫分组
            "filter" : { "term": { "type": "t-shirt" } },
            "aggs" : {//第二层 平均值   子统计查询
                "avg_price" : { "avg" : { "field" : "price" } }
            }
        }
    }
}

Response: 

{
    ...
    "aggregations" : {
        "t_shirts" : {
            "doc_count" : 3,
            "avg_price" : { "value" : 128.33333333333334 }
        }
    }
}

Java代码:

TermQueryBuilder termQueryBuilder = new TermQueryBuilder("type","t-shirt");
        AggregationBuilders.filter("t_shirts",termQueryBuilder).subAggregation(AggregationBuilders.avg("avg_price").field("field"));

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值