ElasticSearch(12)Java API高级查询(常用重点)

在这里插入图片描述

matchAll查询

matchAll查询:查询所有文档

package com.yy.esdemo;

import com.alibaba.fastjson.JSON;
import com.yy.esdemo.domain.Person;
import com.yy.esdemo.domain.User;
import com.yy.esdemo.mapper.UserMapper;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class demo4 {
    @Autowired
    private RestHighLevelClient client;

    /**
     * 查询所有
     *      1. matchALL
     *      2.将查询结果封装为Person对象,装载到List中
     *      3.分页。默认显示10条
     */
    @Test
    public void matchAllTest() throws IOException {
        //2 构建查询请求对象,指定查询的索引名称
        SearchRequest searchRequest = new SearchRequest("person");
        //4 创建查询条件构建器 SearchSourceBuilder
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //6 查询条件
        QueryBuilder query = QueryBuilders.matchAllQuery();
        // 5 指定查询条件
        sourceBuilder.query(query);

        //3 添加查询条件构建器SearchSourceBuilder
        searchRequest.source(sourceBuilder);
        //1 查询,获取查询结果
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        // 7 获取命中对象 SearchHits
        SearchHits searchHits = searchResponse.getHits();
        //7.1 获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:"+value);

        List<Person> lists = new ArrayList<>();
        //7.2 获取Hits数据,这个是一个数组
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits){
            //获取json字符串格式的数据
            String sourceAsString = hit.getSourceAsString();
            //转为java对象
            Person person = JSON.parseObject(sourceAsString, Person.class);

            lists.add(person);

        }
        for (Person person : lists){
            System.out.println(person);
        }

    }
}

在这里插入图片描述
进行分页查询:

 /**
     * 查询所有
     *      1. matchALL
     *      2.将查询结果封装为Person对象,装载到List中
     *      3.分页。默认显示10条
     */
    @Test
    public void matchAllTest() throws IOException {
        //2 构建查询请求对象,指定查询的索引名称
        SearchRequest searchRequest = new SearchRequest("person");
        //4 创建查询条件构建器 SearchSourceBuilder
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //6 查询条件
        QueryBuilder query = QueryBuilders.matchAllQuery();
        // 5 指定查询条件
        sourceBuilder.query(query);

        //3 添加查询条件构建器SearchSourceBuilder
        searchRequest.source(sourceBuilder);

        //8 添加分页信息
        sourceBuilder.from(0);
        sourceBuilder.size(3);

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

        // 7 获取命中对象 SearchHits
        SearchHits searchHits = searchResponse.getHits();
        //7.1 获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:"+value);

        List<Person> lists = new ArrayList<>();
        //7.2 获取Hits数据,这个是一个数组
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits){
            //获取json字符串格式的数据
            String sourceAsString = hit.getSourceAsString();
            //转为java对象
            Person person = JSON.parseObject(sourceAsString, Person.class);

            lists.add(person);

        }
        for (Person person : lists){
            System.out.println(person);
        }

    }

在这里插入图片描述

termQuery查询

term查询:不会对查询条件进行分词。

/**
     * termQuery:词条查询
     */
    @Test
    public void testTermQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.termQuery("address","北京");

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:"+value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits){
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

matchQuery查询

match查询:

  • 会对查询条件进行分词
  • 然后将分词后的查询条件和词条进行等值匹配
  • 默认取并集(OR)
Test
    public void testMatchQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        QueryBuilder query = QueryBuilders.matchQuery("address","北京外滩");

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:"+value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits){
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述
指定交集或并集

 @Test
    public void testMatchQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        MatchQueryBuilder query = QueryBuilders.matchQuery("address","北京外滩");
        query.operator(Operator.AND);


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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:"+value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits){
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

模糊查询

wildcard查询

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

@Test
    public void testWildcardQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        WildcardQueryBuilder query = QueryBuilders.wildcardQuery("address", "w*");

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:"+value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits){
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
}

在这里插入图片描述

regexp查询

regexp查询:正则查询

@Test
    public void testRegexpdQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        RegexpQueryBuilder query = QueryBuilders.regexpQuery("address", "\\w+(.)*");

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

prefix查询

prefix查询:前缀查询

@Test
    public void testPrefixQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        PrefixQueryBuilder query = QueryBuilders.prefixQuery("name", "王");

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

范围查询

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

 @Test
    public void testERangeQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        RangeQueryBuilder query = QueryBuilders.rangeQuery("age");
        //指定下限
        query.gte(25);
        //指定上限
        query.lte(45);

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

排序查询

@Test
    public void testERangeQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        RangeQueryBuilder query = QueryBuilders.rangeQuery("age");
        //指定下限
        query.gte(25);
        //指定上限
        query.lte(45);

        sourceBuilder.query(query);

        //排序
        sourceBuilder.sort("age", SortOrder.DESC);

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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

queryString查询

queryString:

  • 会对查询条件进行分词
  • 然后将分词后的查询条件和词条进行等值匹配
  • 默认取并集(OR)
  • 可以指定多个查询字段
@Test
    public void testQueryStringQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        QueryStringQueryBuilder query = QueryBuilders
                .queryStringQuery("北京外滩")
                .field("address").field("name")
                .defaultOperator(Operator.AND);


        sourceBuilder.query(query);


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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

布尔查询

boolQuery:对多个查询条件连接。

连接方式:

  • must (and):条件必须成立
  • must_not (not):条件必须不成立.
  • should (or):条件可以成立
  • filter:条件必须成立,性能比must高。不会计算得分
/**
     * 查询姓名以王开头,地址包含北京,年龄在45岁以下,
     * @throws IOException
     */
    @Test
    public void testBooleanQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 1 构建boolQuery
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        // 2 构建各个查询条件
        // 2.1 地址包含北京
        TermQueryBuilder termQuery = QueryBuilders.termQuery("address", "北京");
        query.must(termQuery);
        // 2.2 查询姓名以王开头
        WildcardQueryBuilder wildcardQuery = QueryBuilders.wildcardQuery("name", "王*");
        query.must(wildcardQuery);
        // 3 年龄在45岁以下
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
        rangeQuery.gte(18);
        rangeQuery.lte(45);
        query.filter(rangeQuery);


        sourceBuilder.query(query);


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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }
    }

在这里插入图片描述

聚和查询

指标聚合

指标聚合:相当于MySQL的聚合函数。max、min、avg、sum等


桶聚合

桶聚合:相当于MySQL的group by操作。不要对text类型的数据进行分组,会失败。

/**
     * 查询姓名包含王的地址列表
     * @throws IOException
     */
    @Test
    public void testAggQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        MatchQueryBuilder query = QueryBuilders.matchQuery("address", "外滩");

        sourceBuilder.query(query);

        //查询地址列表
        /*
        参数:
            1:自定义的名称,将来用于获取数据
            2.分组的字段
         */
        AggregationBuilder agg = AggregationBuilders.terms("ages").field("age").size(10);
        sourceBuilder.aggregation(agg);


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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);
            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }

        //获取聚会结果
        Aggregations aggregations = searchResponse.getAggregations();
        //将结果转为map
        Map<String, Aggregation> aggregationMap = aggregations.asMap();
        //获取结果中上面定义的ages里面的数据,并将结果转为Term类型
        Terms ages = (Terms) aggregationMap.get("ages");
        //获取桶里面的数据
        List<? extends Terms.Bucket> buckets = ages.getBuckets();
        //将桶中的age数据获取到
        List ageLists = new ArrayList();
        for (Terms.Bucket bucket : buckets) {
            Object key = bucket.getKey();
            ageLists.add(key);
        }
        for (Object ageList : ageLists) {
            System.out.println(ageList);
        }


    }

在这里插入图片描述

高亮查询

/**
     *高亮查询:
     * 1。设置高亮
     *      高亮字段
     *      前缀
     *      后缀
     * 2.将高亮了的字段数据,替换原有数据
     *
     * @throws IOException
     */
    @Test
    public void testHighLightQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("person");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        MatchQueryBuilder query = QueryBuilders.matchQuery("address", "北京");

        sourceBuilder.query(query);

        //设置高亮
        HighlightBuilder highLight = new HighlightBuilder();
        //设置三要素
        highLight.field("address");//字段名
        highLight.preTags("<font color='red'>");
        highLight.postTags("</font>");

        sourceBuilder.highlighter(highLight);

        //查询地址列表
        /*
        参数:
            1:自定义的名称,将来用于获取数据
            2.分组的字段
         */
        AggregationBuilder agg = AggregationBuilders.terms("ages").field("age").size(10);
        sourceBuilder.aggregation(agg);


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

        SearchHits searchHits = searchResponse.getHits();
        //获取总记录数
        long value = searchHits.getTotalHits().value;
        System.out.println("总记录数:" + value);

        List<Person> lists = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();


        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转为json
            Person person = JSON.parseObject(sourceAsString, Person.class);

            Map<String, SearchHits> innerHits = hit.getInnerHits();

            //获取高亮结果,替换address中的结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("address");
            Text[] fragments = highlightField.fragments();
            //替换
            person.setAddress(fragments[0].toString());

            lists.add(person);
        }

        for (Person list : lists) {
            System.out.println(list);
        }

        //获取聚会结果
        Aggregations aggregations = searchResponse.getAggregations();
        //将结果转为map
        Map<String, Aggregation> aggregationMap = aggregations.asMap();
        //获取结果中上面定义的ages里面的数据,并将结果转为Term类型
        Terms ages = (Terms) aggregationMap.get("ages");
        //获取桶里面的数据
        List<? extends Terms.Bucket> buckets = ages.getBuckets();
        //将桶中的age数据获取到
        List ageLists = new ArrayList();
        for (Terms.Bucket bucket : buckets) {
            Object key = bucket.getKey();
            ageLists.add(key);
        }
        for (Object ageList : ageLists) {
            System.out.println(ageList);
        }
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值