GET /person/_search
{
"查询": {
“布尔”:{
“必须”: [
{
"术语": {
“性别”: {
“价值”:"女",
"提升": 1.0
}
}
},
{
"范围": {
"年龄": {
"来自":30,
“到” :40,
“include_lower”:true, “include_upper”:true,
“提升”: 1.0
}
}
}
],
“不得”: [
{
“术语”:{
“教派关键字”:{ “值”:“明教”,
“提升”:1.0
}
}
}
],
“应该”: [
{
“术语”: {
“地址.关键字”: “提升”:1.0
}
}
},
“技能.关键词”:{
“值”:“隐藏武器”,
“提升”:1.0
}
}
}
],
“调整纯负值”: true,
“最小_应该_匹配”:” 1",
"增强": 1.0
}
}
}
用 Java 构建此查询条件:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 构建查询语句
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("性别", "女"))
.must(QueryBuilders.rangeQuery("年龄") .gte(30).lte(40 ))
.mustNot(QueryBuilders.termQuery("sect.keyword", "明教")) .should(QueryBuilders.termQuery("地址.keyword", "峨眉山"))
.should(QueryBuilders.rangeQuery("power.keyword" ).gte(50).lte( 80))
.minimumShouldMatch(1); //设置应该至少需要满足几个条件
//将BoolQueryBuilder构建到SearchSourceBuilder中
searchSourceBuilder.query(boolQueryBuilder);
2.2 过滤查询
query和filter的区别:查询查询的时候,会先比较查询条件,然后计算分值,最后返回文档结果;而filter是先判断是否满足查询条件,如果不满足会缓存查询结果(记录该)文档不满足结果),满足的话,就直接存储结果,过滤器不会对结果进行评分,能够提高查询效率。
过滤器有多种用途。这里有几个例子来演示它。
方法一,单独使用:
{
“查询”:{
“过滤”:[
{
“术语”:{
“性别”:{ “价值”: “男” ) | 真,
“提升”:1.0
}
}
}
单独使用时,过滤器与必须的基本相同。不同的是filter不计算分数,效率更高。
Java构建查询语句:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建查询语句
searchSourceBuilder.query(QueryBuilder s.boolQuery() .filter(QueryBuilders.termQuery(“性别”, “男”))
);
方法二,与must和must_not同级,相当于子查询:
选择 * 来自(选择 * 来自 人其中宗='明教' )) a 其中性别 = '女';
ES查询语句:
{
“查询”:{
“必须”: [
{
"术语": {
“sect.keyword”:{
“值”:《明教》,
《升压》 : 1.0
}
}
}
],
“过滤器”:[
:{
“价值”: “女”,
“提升”: 1.0
}
}
}
:true,
“增强”:1.0
}
}
}
Java:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建查询语句
searchSourceBuilder.query(QueryBuilder s.boolQuery() .must(QueryBuilders.termQuery( "sect.keyword", "明教"))
.filter(QueryBuilders.termQuery("性别) ”,“女” ) )
);
方法三,将must和must_not放在过滤器下。这种方法最常用:
{
“查询”:{
“布尔”: {
“筛选”: [
{
“布尔”: {
“必须”: [ {
“术语”: {
“教派关键字”: {
“值”: “明教”,
“提升”:1.0
}
}
},
{
“范围”: {
“年龄”: {
"从": 20,
"到": 35,
“include_lower”: true,
"include_upper": true,
“提升”:1.0
}
}
}
],
“不得”: [
{
“术语”: {
“性别.关键字” : {
"值": "女", “提升”:1.0
}
}
}
],
“调整纯负” :true,
“提升”:1.0
}
}
],
“调整纯负”: true,
“提升”:1.0
}
}
}
Java:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 构建查询语句
searchSourceBuilder.query(QueryBuilders.boolQuery() .filter(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("sect.keyword", "明教"))
.must(QueryBuilders.rangeQuery("年龄" ).gte(20).lte(35))
.mustNot(QueryBuilders.termQuery("性别.关键字", “女”)))
);
3聚合查询
接下来,我们将用一些ES聚合查询案例进行演示。
3.1 最低值、干、求和
案例:查询最大年龄、最小年龄、平均年龄。
SQL:
从人中选择 最大(年龄);
ES:
GET /person/_search
{
“聚合”: {
“最大年龄”:{
“最大”: {
“田地”: “年龄”
}
}
}
}
Java:
@Autowired
私有 RestHighLevelClient 客户端;
@Test
公共 void maxQueryTest() throws IOException {
//聚合查询条件
AggregationBuilder aggBuilder = AggregationBuilders.max( " max_age").field("年龄");
SearchRequest searchRequest = new SearchRequest("人");
SearchSourceBuilder searchSourceBuilder = newSearchSourceBuilder();
// 将聚合查询条件构建到SearchSourceBuilder
searchSourceBuilder.aggregation(aggBuilder);
System.out.println("searchSourceBuilder----->" + searchSourceBuilder);
searchRequest.source(searchSourceBuilder);
//执行查询并获取SearchResponse
SearchResponse response = www.sychzs.cn(searchRequest, RequestOptions.DEFAULT); System.out.println (JSONObject .toJSON(响应));
}
使用聚合查询,结果中默认只会返回10条文档数据(当然我们关心的是聚合结果,而不是文档)。您可以控制返回多少条数据:
GET /person/_search
{
"尺寸": 20,
“聚合”:{
” max_age": {
"最大": {
"字段" : “年龄”
}
}
}
}
在Java中,只需添加以下语句:
searchSourceBuilder.size(20);
和max类似,其他统计查询也很简单:
AggregationBuilder minBuilder = AggregationBuilders.min("min_age").field("age");
AggregationBuilder avgBuilder = AggregationBuilders.avg("min_age").field("age");
AggregationBuilder sumBuilder = AggregationBuilders.sum("min_age").field("age");
AggregationBuilder countBuilder = AggregationBuilders.count("min_age").field("age");
3.2 去重查询
案例:查询一共有多少个门派。
SQL:
select count(distinct sect) from persons;
ES:
{
"aggregations": {
"sect_count": {
"cardinality": {
"field": "sect.keyword"
}
}
}
}
Java:
@Test
public void cardinalityQueryTest() throws IOException {
// 创建某个索引的request
SearchRequest searchRequest = new SearchRequest("person");
// 查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 聚合查询
AggregationBuilder aggBuilder = AggregationBuilders.cardinality("sect_count").field("sect.keyword");
searchSourceBuilder.size(0);
// 将聚合查询构建到查询条件中
searchSourceBuilder.aggregation(aggBuilder);
System.out.println("searchSourceBuilder----->" + searchSourceBuilder);
searchRequest.source(searchSourceBuilder);
// 执行查询,获取结果
SearchResponse response = www.sychzs.cn(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSON(response));
}
3.3 分组聚合
3.3.1 单条件分组
案例:查询每个门派的人数
SQL:
select sect,count(id) from mytest.persons group by sect;
ES:
{
"size": 0,
"aggregations": {
"sect_count": {
"terms": {
"field": "sect.keyword",
"size": 10,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
}
}
}
Java:
SearchRequest searchRequest = new SearchRequest("person");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(0);
// 按sect分组
AggregationBuilder aggBuilder = AggregationBuilders.terms("sect_count").field("sect.keyword");
searchSourceBuilder.aggregation(aggBuilder);
3.3.2 多条件分组
案例:查询每个门派各有多少个男性和女性
SQL:
select sect,sex,count(id) from mytest.persons group by sect,sex;
ES:
{
"aggregations": {
"sect_count": {
"terms": {
"field": "sect.keyword",
"size": 10
},
"aggregations": {
"sex_count": {
"terms": {
"field": "sex.keyword",
"size": 10
}
}
}
}
}
}
3.4 过滤聚合
前面所有聚合的例子请求都省略了 query ,整个请求只不过是一个聚合。这意味着我们对全部数据进行了聚合,但现实应用中,我们常常对特定范围的数据进行聚合,例如下例。
案例:查询明教中的最大年龄。这涉及到聚合与条件查询一起使用。
SQL:
select max(age) from mytest.persons where sect = '明教';
ES:
GET /person/_search
{
"query": {
"term": {
"sect.keyword": {
"value": "明教",
"boost": 1.0
}
}
},
"aggregations": {
"max_age": {
"max": {
"field": "age"
}
}
}
}
Java:
SearchRequest searchRequest = new SearchRequest("person");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 聚合查询条件
AggregationBuilder maxBuilder = AggregationBuilders.max("max_age").field("age");
// 等值查询
searchSourceBuilder.query(QueryBuilders.termQuery("sect.keyword", "明教"));
searchSourceBuilder.aggregation(maxBuilder);
另外还有一些更复杂的查询例子。
案例:查询0-20,21-40,41-60,61以上的各有多少人。
SQL:
select
sum(case when age<=20 then 1 else 0 end) ageGroup1,
sum(case when age >20 and age <=40 then 1 else 0 end) ageGroup2,
sum(case when age >40 and age <=60 then 1 else 0 end) ageGroup3,
sum(case when age >60 and age <=200 then 1 else 0 end) ageGroup4
from
mytest.persons;
ES:
{
"size": 0,
"aggregations": {
"age_avg": {
"range": {
"field": "age",
"ranges": [
{
"from": 0.0,
"to": 20.0
},
{
"from": 21.0,
"to": 40.0
},
{
"from": 41.0,
"to": 60.0
},
{
"from": 61.0,
"to": 200.0
}
],
"keyed": false
}
}
}
}
查询结果:
"aggregations" : {
"age_avg" : {
"buckets" : [
{
"key" : "0.0-20.0",
"from" : 0.0,
"to" : 20.0,
"doc_count" : 3
},
{
"key" : "21.0-40.0",
"from" : 21.0,
"to" : 40.0,
"doc_count" : 13
},
{
"key" : "41.0-60.0",
"from" : 41.0,
"to" : 60.0,
"doc_count" : 4
},
{
"key" : "61.0-200.0",
"from" : 61.0,
"to" : 200.0,
"doc_count" : 1
}
]
}
}
以上是ElasticSearch查询的全部内容,丰富详实,堪比操作手册,强烈建议收藏!