ES高级查询

25 篇文章 0 订阅

ES高级查询

1. 导入依赖

  <!--引入es的坐标-->
        <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.6.1</version>
        </dependency>


        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.68</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
<!--      解决  Spring Boot Configuration Annotation Processor not configured-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

2. 配置文件

elasticsearch:
  hostname: 192.168.153.132
  port: 9200

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///test
    username: root
    password: ****


mybatis-plus:
  configuration:
    #关闭驼峰标识
    map-underscore-to-camel-case: false
    #控制台显示sql语句
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    #逻辑删除
    db-config:
      logic-not-delete-value: 1
      logic-delete-value: 0
      #加载我们的xml文件
  mapper-locations: classpath:/mappers/xml/*.xml
  type-aliases-package: com.wy.pojo

3. 配置类

package com.wy.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@ConfigurationProperties(prefix="elasticsearch")
public class ElasticSearchConfig {

    private String hostname;
    private int port;


    @Bean
    public RestHighLevelClient client(){
        return new RestHighLevelClient(RestClient.builder(
                new HttpHost(hostname,port,"http")
        ));
    }

    public String getHostname() {
        return hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

4. mapper

package com.wy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wy.pojo.Goods;

public interface GoodsMapper extends BaseMapper<Goods> {
}

5. 启动类

package com.wy;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.wy.mapper")
public class EstestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EstestApplication.class, args);
    }

}

6.从Mysql 批量导入 elasticSearch

/**
 * 从Mysql 批量导入 elasticSearch
 */
@Test
public void test3() throws IOException {
    //1.查询所有数据,mysql
    List<Goods> goodsList = goodsMapper.selectList(null);
    //2.bulk导入
    BulkRequest bulkRequest=new BulkRequest();
    //2.1 循环goodsList,创建IndexRequest添加数据
    for (Goods goods : goodsList) {
        //2.2 设置spec规格信息 Map的数据   specStr:{}
        String specStr = goods.getSpecStr();
        //将json格式字符串转为Map集合
        Map<String, Object> map = JSON.parseObject(specStr, Map.class);
        //设置spec map
        goods.setSpec(map);
        //将goods对象转换为json字符串
        String data = JSON.toJSONString(goods);
        IndexRequest indexRequest=new IndexRequest("goods").source(data,XContentType.JSON);
        bulkRequest.add(indexRequest);

    }
    BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    System.out.println(response.status());
}

7. matchAll查询所有

脚本实现

# 默认情况下,es一次展示10条数据,通过from和size来控制分页
# 查询结果详解

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

JavaAPI

/**
 * matchAll查询所有
 */
@Test
public void matchAll() throws IOException {
    // 1.创建查询请求
    SearchRequest goodsSearchRequest = new SearchRequest("goods");
    // 2.创建条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.配置查询条件
    MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
    searchSourceBuilder.query(matchAllQueryBuilder);
    // 4.向请求中添加查询条件构建器
    goodsSearchRequest.source(searchSourceBuilder);
    // 5.添加分页信息,不配置默认10条
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(100);

    // 6.执行查询,获取查询结果
    SearchResponse searchResponse = restHighLevelClient.search(goodsSearchRequest, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    // 获取命中的总记录数
    long total = hits.getTotalHits().value;
    System.out.println(">>>>>>>>>总数:" + total);
    // 获取命中的数据
    SearchHit[] hitsList = hits.getHits();
    for (SearchHit documentFields : hitsList) {
        String data = documentFields.getSourceAsString();
        Goods goods = JSON.parseObject(data, Goods.class);

        // 打印查询结果
        System.out.println(">>>>>>>>>>" + goods);
    }

}

8. termQuery 词条查询

脚本实现

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

JavaAPI

/**
 * termQuery 词条查询
 * 直接对给定条件查询
 */
@Test
public void termQuery() throws IOException {
    // 1.获取查询请求
    SearchRequest goods = new SearchRequest("goods");
    // 2.创建条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.条件配置
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "华为");
    searchSourceBuilder.query(termQueryBuilder);
    // 4.配置分页
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(3);
    // 5.向请求中注入条件
    goods.source(searchSourceBuilder);
    // 6.执行查询
    SearchResponse searchResponse = restHighLevelClient.search(goods, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    // 获取命中总记录数
    TotalHits totalHits = hits.getTotalHits();
    System.out.println(">>>>>>>>>>>>>total: " + totalHits);

    // 获取命中的的数据(分页后)
    hits.forEach(hit -> {
        String data = hit.getSourceAsString();
        Goods dataGood = JSON.parseObject(data, Goods.class);
        System.out.println(dataGood);
    });
}

9. matchQuery

脚本实现

# match查询
GET goods/_search
{
  "query": {
    "match": {
      "title": "华为手机"
    }
  },
  "size": 500
}

JavaAPI

/**
 * matchQuery
 * match查询,会对查询条件分词,然后将分词后的查询条件和词条进行等值匹配,默认取并集
 */
@Test
public void matchQuery() throws IOException {
    // 1.获取查询请求
    SearchRequest goods = new SearchRequest("goods");
    // 2.创建条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.条件配置
    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "华为手机");
    searchSourceBuilder.query(matchQueryBuilder);
    // 4.配置分页
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(3);
    // 5.向请求中注入条件
    goods.source(searchSourceBuilder);
    // 6.执行查询
    SearchResponse searchResponse = restHighLevelClient.search(goods, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    // 获取命中总记录数
    TotalHits totalHits = hits.getTotalHits();
    System.out.println(">>>>>>>>>>>>>total: " + totalHits);

    // 获取命中的的数据(分页后)
    hits.forEach(hit -> {
        String data = hit.getSourceAsString();
        Goods dataGood = JSON.parseObject(data, Goods.class);
        System.out.println(dataGood);
    });
}

10. wildcardQuery 模糊查询

脚本实现

# wildcard 查询。查询条件分词,模糊查询
GET goods/_search
{
  "query": {
    "wildcard": {
      "title": {
        "value": "华*"
      }
    }
  }
}

JavaAPI

/**
 * wildcardQuery
 * 模糊查询 ?代表任意单个字符,*代表0个或者是多个字符
 */
@Test
public void wildcardQuery() throws IOException {
    // 1.获取查询请求
    SearchRequest goods = new SearchRequest("goods");
    // 2.创建条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.条件配置
    WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("title", "华*");//华后多个字符
    searchSourceBuilder.query(wildcardQueryBuilder);
    // 4.配置分页
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(3);
    // 5.向请求中注入条件
    goods.source(searchSourceBuilder);
    // 6.执行查询
    SearchResponse searchResponse = restHighLevelClient.search(goods, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    // 获取命中总记录数
    TotalHits totalHits = hits.getTotalHits();
    System.out.println(">>>>>>>>>>>>>total: " + totalHits);

    // 获取命中的的数据(分页后)
    hits.forEach(hit -> {
        String data = hit.getSourceAsString();
        Goods dataGood = JSON.parseObject(data, Goods.class);
        System.out.println(dataGood);
    });
}

11. rangeQuery范围查询

脚本实现

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

JavaAPI

/**
 * rangeQuery
 * 范围查询 gte >= lte <=
 */
@Test
public void rangeQuery() throws IOException {
    // 1.获取查询请求
    SearchRequest goods = new SearchRequest("goods");
    // 2.创建条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.条件配置
    //范围查询 以price 价格为条件
    RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
    //指定下限
    rangeQueryBuilder.gte(2000);
    //指定上限
    rangeQueryBuilder.lte(3000);
    searchSourceBuilder.query(rangeQueryBuilder);

    //排序  价格 降序排列
    searchSourceBuilder.sort("price",SortOrder.DESC);
    // 4.配置分页
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(3);
    // 5.向请求中注入条件
    goods.source(searchSourceBuilder);
    // 6.执行查询
    SearchResponse searchResponse = restHighLevelClient.search(goods, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    // 获取命中总记录数
    TotalHits totalHits = hits.getTotalHits();
    System.out.println(">>>>>>>>>>>>>total: " + totalHits);

    // 获取命中的的数据(分页后)
    hits.forEach(hit -> {
        String data = hit.getSourceAsString();
        Goods dataGood = JSON.parseObject(data, Goods.class);
        System.out.println(dataGood);
    });
}

12. queryString多条件查询

脚本实现

# queryString
GET goods/_search
{
  "query": {
    "query_string": {
      "fields": ["title","categoryName","brandName"], 
      "query": "华为 AND 手机"
    }
  }
}

JavaAPI

/**
 * queryString
 * 多条件查询
 * 会对查询条件进行分词。
 * 然后将分词后的查询条件和词条进行等值匹配
 * 默认取并集(OR)
 * 可以指定多个查询字段
 * query_string:识别query中的连接符(or 、and)
 */
@Test
public void queryString () throws IOException {
    // 1.获取查询请求
    SearchRequest goods = new SearchRequest("goods");
    // 2.创建条件构建器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.条件配置
    //多条件查询【会对查询条件进行分词,然后对三个字段取并集,只要三个字段的并集结果可以与任意分词结果匹配则命中】
    QueryStringQueryBuilder query = QueryBuilders.queryStringQuery("华为手机").field("title").field("categoryName")
            .field("brandName").defaultOperator(Operator.AND);
    searchSourceBuilder.query(query);
    // 4.配置分页
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(300);
    // 5.向请求中注入条件
    goods.source(searchSourceBuilder);
    // 6.执行查询
    SearchResponse searchResponse = restHighLevelClient.search(goods, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    // 获取命中总记录数
    TotalHits totalHits = hits.getTotalHits();
    System.out.println(">>>>>>>>>>>>>total: " + totalHits);

    // 获取命中的的数据(分页后)
    hits.forEach(hit -> {
        String data = hit.getSourceAsString();
        Goods dataGood = JSON.parseObject(data, Goods.class);
        System.out.println(dataGood);
    });
}

13. aggQuery聚合查询

脚本实现

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

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

JavaAPI

/**
 * 聚合查询
 * 指标聚合:相当于MySQL的聚合函数。max、min、avg、sum等
 * 桶聚合:相当于MySQL的 group by 操作。不能对text类型的数据进行分组
 */
@Test
public void aggQuery() throws IOException {
    // 1.获取查询请求
    SearchRequest goods = new SearchRequest("goods");
    // 2.创建条件构建器

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 3.普通查询条件设置
    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
    searchSourceBuilder.query(matchQueryBuilder);

    // 4.桶聚合查询, 指定分组的依据对象
    // 查询品牌列表,只展示前100条
    TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("goods_brands").field("brandName").size(100);
    searchSourceBuilder.aggregation(termsAggregationBuilder);
    // 配置分页
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(300);
    // 5.装配查询条件
    goods.source(searchSourceBuilder);
    // 6.执行查询
    SearchResponse searchResponse = restHighLevelClient.search(goods, RequestOptions.DEFAULT);
    // 7.获取命中对象
    SearchHits hits = searchResponse.getHits();

    long total = hits.getTotalHits().value;
    System.out.println(">>>>>>>>>>>>>总记录数:" + total);
    // 获取桶查询结果
    Aggregations aggregations = searchResponse.getAggregations();
    Map<String, Aggregation> aggregationMap = aggregations.asMap();
    Terms goodsBrands = (Terms) aggregationMap.get("goods_brands");
    List<? extends Terms.Bucket> buckets = goodsBrands.getBuckets();
    buckets.forEach(bucket -> {
        System.out.println(bucket.getKeyAsString() + ": " + bucket.getDocCount());
    });

}

总结

不同的查询,只是改变了查询条件。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值