ElasticSearch之高级查询

查询操作

matchAll查询:查询所有文档

脚本操作

GET goods/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  }
}

默认分页显示,每页显示10条记录

使用from和size可以进行控制。指定从哪儿开始,每页展示多少条

GET goods/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },"from": 0,
    "size": 100
}

max_score得分,根据得分进行排序,得分越高,排序越靠前

结果详解

 "took" : 1,                #花费的时间
  "timed_out" : false,	    #是否超时	
  "_shards" : {
    
    			    #分片信息	
    "total" : 1,			#总共1片
    "successful" : 1,		#成功1片
    "skipped" : 0,			#跳过1片
    "failed" : 0			#失败1片
  },
  "hits" : {
    
    				#命中
    "total" : {
    
    
      "value" : 940,		#总共命中940条	
      "relation" : "eq"		#操作方式:等值查询
    },
    "max_score" : 1.0,		#得分,根据得分进行排序
    "hits" : [				#命中的数据,是一个数组
      {
    
    
        "_index" : "goods",
        "_type" : "_doc",
        "_id" : "1",		#文档的唯一标识
        "_score" : 1.0,
        "_source" : {
    
    		#真实的数据
          "title" : "小米手机",
          "price" : 1000,
          "createTime" : "2019-12-01",
          "categoryName" : "手机",
          "brandName" : "小米",
          "saleNum" : 3000,
          "stock" : 10000,
          "spec" : {
    
    
            "网络制式" : "移动4G",
            "屏幕尺寸" : "4.5"
          }
        }
      },

JavaAPI操作

/**
     * 查询所有
     * 1.matchAll
     *2.将查询出来的每一条记录封装为一个Goods对象,装载到list集合中
     * */
    @Test
    public void test03() throws IOException {
    
    

        //2.构建查询请求对象,指定查询的索引名称
        SearchRequest searchRequest = new SearchRequest("goods");

        //4.创建条件构建器 SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //6.查询条件
        QueryBuilder query = QueryBuilders.matchAllQuery();

        //5.指定查询条件
        searchSourceBuilder.query(query);

        //3.查询条件构建器
        searchRequest.source(searchSourceBuilder);

        //8.添加分页
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(100);

        //1.查询,获取结果
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //7.获取命中对象 hits
        SearchHits hits = searchResponse.getHits();

        //7.1获取总记录数
        long value = hits.getTotalHits().value;

        System.out.println("总记录数:"+value);

        //获取hits数组
        SearchHit[] hits1 = hits.getHits();

        //创建一个集合用来存储从ES中查出来的每一条记录
        List<Goods> list = new ArrayList();

        for (SearchHit hit : hits1) {
    
    

            //获取到hits中的每一个source
            String sourceAsString = hit.getSourceAsString();

            //将source中的数据封装为Goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);

            //将封装好的对象添加到集合中
            list.add(goods);
        }

        //遍历集合
        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }


    }

term查询

不会对查询条件进行分词,必须精准匹配

脚本操作

#term查询
GET goods/_search
{
    
    
  "query": {
    
    
    "term": {
    
    
      "title": {
    
    
        "value": "华为"
      }
    }
  }
}



GET goods

GET goods/_search
{
    
    
  "query": {
    
    
    "term": {
    
    
      "categoryName": {
    
    
        "value": "手机"
      }
    }
  }
}

JavaAPI操作

/**
     *
     * term词条查询
     *
     * */
    @Test
    public void test04() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.termQuery("title","华为");   //term词条查询

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }
    }

match查询

​ 会对查询条件进行分词

​ 然后对分词后的词条进行分别查询

​ 再对结果取并集,默认并集(也可以指定为交集OR)

match查询—脚本

#match查询  会进行分词查询
GET goods/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "title": "华为手机"
    }
  }
}

#指定取交集还是并集
GET goods/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "title": {
    
    
        "query": "华为手机"
        ,"operator": "and"
      }
    }
  }
}

JavaAPI操作

/**
     *
     * match词条查询
     *
     * */
    @Test
    public void test05() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.matchQuery("title","华为手机");   //term词条查询

        ((MatchQueryBuilder) query).operator(Operator.OR);  //取并集


        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

模糊查询:在前面加通配符会进行全部倒排索引扫描,之前建立的索引会失效,性能会较低

wildcard查询:会对查询条件进行分词。还可以使用通匹配符?(任意单个字符)和*(0或多个字符)

regexp查询:正则查询

prefix查询:前缀查询

脚本操作

#wildcard查询。查询条件分词,模糊查询 在前面加通配符会进行全部倒排索引扫描,之前建立的索引会失效
GET goods/_search
{
    
    
  "query": {
    
    
    "wildcard": {
    
    
      "title": {
    
    
        "value": "华*"
      }
    }
  }
}



#正则查询
GET goods/_search
{
    
    
  "query": {
    
    
    "regexp": {
    
    
      "title": "\\w+(.)*"
    }
  }
}


#前缀查询  对keyword支持较好

GET goods/_search
{
    
    
  "query": {
    
    
    "prefix": {
    
    
      "brandName": {
    
    
        "value": "三"
      }
    }
  }
}

JavaAPI

wildcard查询:

/**
     *
     * wildcard模糊查询
     *
     * */
    @Test
    public void test06() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.wildcardQuery("title", "华*");

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

regexp查询:正则查询

 /**
     *
     * Regexp模糊查询
     *
     * */
    @Test
    public void test07() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.regexpQuery("title", "\\w+(.)*");

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

prefix查询:前缀查询

/**
     *
     * prefixQuery前缀模糊查询
     *
     * */
    @Test
    public void test08() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.prefixQuery("brandName", "三");

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

范围查询

range范围查询:查找指定字段在指定范围内包含值

应用场景
在这里插入图片描述

脚本操作

#范围查询
GET goods/_search
{
    
    
  "query": {
    
    
    "range": {
    
    
      "price": {
    
    
        "gte": 2000,
        "lte": 3000
      }
    }
  }
}

JavaAPI操作

 /**
     *
     * range范围查询
     *
     * */
    @Test
    public void test09() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.rangeQuery("price");

        //指定上限
        ((RangeQueryBuilder) query).gte(2000);

        //指定下限
        ((RangeQueryBuilder) query).lte(3000);

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

所有的查询均可进行排序

对范围查询出来的结果进行排序操作

#范围查询 排序  对查询出来的结果进行排序
#asc升序
#desc降序

GET goods/_search
{
    
    
  "query": {
    
    
    "range": {
    
    
      "price": {
    
    
        "gte": 2000,
        "lte": 3000
      }
    }
  },"sort": [
    {
    
    
      "price": {
    
    
        "order": "asc"
      }
    }
  ]
}

JavaAPI操作

    /**
     *
     * range范围查询
     *并对其进行排序
     * */
    @Test
    public void test10() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.rangeQuery("price");

        //对查询结果进行降序排序
        searchSourceBuilder.sort("price", SortOrder.DESC);

        //指定上限
        ((RangeQueryBuilder) query).gte(2000);

        //指定下限
        ((RangeQueryBuilder) query).lte(3000);

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

多字段同时查询

queryString查询

脚本操作

#多字段查询
GET goods/_search
{
    
    
  "query": {
    
    
    "query_string": {
    
    
     "fields": ["title","brandName","categoryName"], 
      "query": "华为 AND 手机"
    }
  }
}


#"simple_query_string不支持连接符
GET goods/_search
{
    
    
  "query": {
    
    
    "simple_query_string": {
    
    
     "fields": ["title","brandName","categoryName"], 
      "query": "华为手机"
    }
  }
}
#多字段查询
GET goods/_search
{
    
    
  "query": {
    
    
    "query_string": {
    
    
     "fields": ["title","brandName","categoryName"], 
      "query": "华为 AND 手机"
    }
  }
}


#"simple_query_string不支持连接符
GET goods/_search
{
    
    
  "query": {
    
    
    "simple_query_string": {
    
    
     "fields": ["title","brandName","categoryName"], 
      "query": "华为手机"
    }
  }
}

JavaAPI操作

 /**
     * queryString多字段查询
     */
    @Test
    public void test11() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //queryString查询
        QueryBuilder query = QueryBuilders.queryStringQuery("华为手机").field("title").field("brandName").field("categoryName").defaultOperator(Operator.AND);

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

布尔查询

脚本操作

#布尔查询 boolQuery
GET goods/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    "term": {
    
    
          "title": {
    
    
            "value": "华为"
          }
        }},{
    
    
        "match": {
    
    
          "categoryName": "手机"
        }  
        }
      ]
    }
  }
}

#filter不会计算得分
GET goods/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "filter": {
    
    
        "term": {
    
    
          "title": "华为"
        }
      }
    }
  }
}
#1.查询品牌名称为:华为
#2.查询标题:手机
#3.查询价格在:2000-3000


GET goods/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    "term": {
    
    
          "brandName": {
    
    
            "value": "华为"
          }
        }}
      ]
      ,"filter":[ {
    
    
        "term": {
    
    
          "title": "手机"
        }
      }
      ,{
    
    
        "range":{
    
    
           "price": {
    
    
           "gte": 2000,
           "lte": 3000
      }
        }
      }        
      ]
      
    }
  }
}

JavaAPI操作

    /**
     * 布尔查询
     * boolQuery
     * <p>
     * 1.查询品牌名称为:华为
     * 2.查询标题:手机
     * 3.查询价格在:2000-3000
     */
    @Test
    public void test12() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //构建boolQuery
        QueryBuilder query = QueryBuilders.boolQuery();

        //1.查询品牌名称为:华为
        QueryBuilder queryBuilders = QueryBuilders.termQuery("brandName","华为");
        ((BoolQueryBuilder) query).must(queryBuilders);

        // 2.查询标题:手机
        QueryBuilder matchQuery = QueryBuilders.matchQuery("title","手机");
        ((BoolQueryBuilder) query).filter(matchQuery);

        //3.查询价格在:2000-3000
        QueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
        ((RangeQueryBuilder) rangeQuery).gte(2000);
        ((RangeQueryBuilder) rangeQuery).lte(3000);
        ((BoolQueryBuilder) query).filter(rangeQuery);

        searchSourceBuilder.query(query);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }

    }

聚合查询

脚本

#聚合函数
#指标聚合
GET goods/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "title":"手机"
    }
  },"aggs": {
    
    
    "max_price": {
    
    
      "max": {
    
    
        "field": "price"
      }
    }
  }
}


#桶聚合 分组
GET goods/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "title": "手机"
    }
  }
  , "aggs": {
    
    
    "goods_brandName": {
    
    
      "terms": {
    
    
        "field": "brandName",
        "size": 100
      }
    }
  }
  
  
}

JavaAPI操作

 /**
     * 聚合查询:桶聚合,分组查询
     * 1.查询title包含手机的数据
     * 2.查询品牌列表
     *
     */
    @Test
    public void test13() throws IOException {
    
    

        SearchRequest searchRequest = new SearchRequest("goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();


        QueryBuilder query = QueryBuilders.matchQuery("title","手机");
        searchSourceBuilder.query(query);

        /*
        * 查询品牌列表
        * 参数:1.自定义排序的名称,将用于获取数据
        *   2.分组的字段
        * */

        TermsAggregationBuilder agg = AggregationBuilders.terms("goods_brand").field("brandName").size(100);

        searchSourceBuilder.aggregation(agg);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        long value = hits.getTotalHits().value;
        System.out.println("总记录数 = " + value);

        SearchHit[] hits1 = hits.getHits();

        List<Goods> list = new ArrayList<>();

        for (SearchHit hit : hits1) {
    
    
            String sourceAsString = hit.getSourceAsString();
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            list.add(goods);
        }


        for (Goods goods : list) {
    
    
            System.out.println(goods);
        }


        //获取聚合结果
        Aggregations aggregations = searchResponse.getAggregations();

        Map<String, Aggregation> stringAggregationMap = aggregations.asMap();

        Terms goods_brand = (Terms) stringAggregationMap.get("goods_brand");

        List<? extends Terms.Bucket> buckets = goods_brand.getBuckets();

        List list1 = new ArrayList();
        for (Terms.Bucket bucket : buckets) {
    
    
            Object key = bucket.getKey();
            list1.add(key);
        }

        for (Object o : list1) {
    
    
            System.out.println(o);
        }

    }

猜你喜欢

转载自blog.csdn.net/zhangzengxiu/article/details/112759857
今日推荐