es快速入门

引入依赖:       

<!--spring boot与es整合依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <!--es的java客户端依赖-->
        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>7.17.5</version>
        </dependency>
        <!--s的java客户端需要的jakarta.json依赖-->
        <dependency>
            <groupId>jakarta.json</groupId>
            <artifactId>jakarta.json-api</artifactId>
            <version>2.0.1</version>
        </dependency>

初始化:

@Data
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticSearchConfig {
    private String host;
    private Integer port;

    @Resource
    private ObjectMapper objectMapper;

    @Bean
    public ElasticsearchClient elasticsearchClient() {
        log.info("es连接ip:{},端口:{}", host, port);
        // 基本的连接
        RestClient restClient = RestClient.builder(new HttpHost(host, port)).build();

        // 使用自定义json序列化
        JacksonJsonpMapper jacksonJsonpMapper = new JacksonJsonpMapper(objectMapper);

        // 基于Jackson mapper创建ElasticsearchTransport
        ElasticsearchTransport transport = new RestClientTransport(restClient, jacksonJsonpMapper);

        // 创建ElasticsearchClient客户端
        return new ElasticsearchClient(transport);
    }
}

配置文件:

elasticsearch:
  host: 192.168.200.102
  port: 9200

布尔查询:

查询案例:

    @Resource
    private ElasticsearchClient elasticsearchClient;

    @Test
    public void testMatchSearch() throws IOException {
        SearchResponse<HotelDoc> response = this.elasticsearchClient.search(builder -> builder
                        .index("hotel") //指定索引库
                        //指定查询条件
                        .query(q -> q.match(m -> m.field("all").query("如家")))
                        //设置分页查询参数
                        .from(0)
                        .size(10),
                HotelDoc.class);

        //获取命中的数据
        HitsMetadata<HotelDoc> hits = response.hits();
        System.out.println("数据总数:" + hits.total().value());
        hits.hits().forEach(hotelDocHit -> {
            System.out.println("得分:"+ hotelDocHit.score());
            System.out.println("数据:"+ hotelDocHit.source());
        });
    }
}

案例:

    @Test
    public void testRangeSearch() throws IOException {
        SearchResponse<HotelDoc> response = this.elasticsearchClient.search(builder -> builder
                        .index("hotel")
                        .query(q ->
                                q.range(r ->
                                        r.field("price")
                                                .gte(JsonData.of("1000"))
                                                .lte(JsonData.of("3000"))
                                )
                        ),
                HotelDoc.class);
        //获取命中的数据JsonData
        HitsMetadata<HotelDoc> hits = response.hits();
        System.out.println("数据总数:" + hits.total().value());
        hits.hits().forEach(hotelDocHit -> {
            System.out.println("得分:" + hotelDocHit.score());
            System.out.println("数据:" + hotelDocHit.source());
        });
    }

案例:

    @Test
    public void tesBoolSearch() throws IOException {
        //查询杭州的酒店,并且价格500元以下的
        SearchResponse<HotelDoc> response = this.elasticsearchClient.search(builder -> builder
                        .index("hotel")
                        .query(q ->
                                q.bool(b ->
                                        b.must(m -> m.term(t -> t.field("city").value("杭州")))
                                                .filter(f ->
                                                        f.range(r -> r.field("price")
                                                                .lte(JsonData.of(500))))
                                )
                        ),
                HotelDoc.class);
        //获取命中的数据JsonData
        HitsMetadata<HotelDoc> hits = response.hits();
        System.out.println("数据总数:" + hits.total().value());
        hits.hits().forEach(hotelDocHit -> {
            System.out.println("得分:" + hotelDocHit.score());
            System.out.println("数据:" + hotelDocHit.source());
        });
    }

案例:

    @Test
    public void testPageAndSort() throws IOException {
        // 页码,每页大小
        int page = 1, size = 5;
        SearchResponse<HotelDoc> response = this.elasticsearchClient.search(builder -> builder
                        .index("hotel")
                        .query(q -> q
                                .matchAll(m -> m)
                        )
                        //排序
                        .sort(s -> s.field(f -> f.field("price").order(SortOrder.Asc)))
                        //分页
                        .size(size).from(page),
                HotelDoc.class);
        //获取命中的数据JsonData
        HitsMetadata<HotelDoc> hits = response.hits();
        System.out.println("数据总数:" + hits.total().value());
        hits.hits().forEach(hotelDocHit -> {
            System.out.println("得分:" + hotelDocHit.score());
            System.out.println("数据:" + hotelDocHit.source());
        });
    }

查询:

@Slf4j
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {

    @Resource
    private ElasticsearchClient elasticsearchClient;

    private static final String INDEX_NAME = "hotel";

    @Override
    public PageResult search(RequestParams params) {
        //1. 构造搜索对象
        Query.Builder queryBuilder = new Query.Builder();
        if (ObjectUtil.isEmpty(params.getKey())) {
            //没有搜索关键词
            queryBuilder.matchAll(m -> m);
        } else {
            queryBuilder.match(m -> m.field("all").query(params.getKey()));
        }
        Query query = queryBuilder.build();

        //2. 计算分页参数
        int size = params.getSize();
        int from = PageUtil.getStart(params.getPage() - 1, size);

        try {
            //3. 执行搜索
            SearchResponse<HotelDoc> response = this.elasticsearchClient.search(builder -> builder
                            .index(INDEX_NAME) //指定索引库
                            .query(query) //指定查询条件
                            .from(from) //设置分页查询参数
                            .trackScores(true) //返回得分值
                            .size(size),
                    HotelDoc.class);

            //处理查询结果
            HitsMetadata<HotelDoc> hits = response.hits();
            //数据列表
            List<HotelDoc> hotelDocList = CollStreamUtil.toList(hits.hits(), Hit::source);
            return new PageResult(hits.total().value(), hotelDocList);
        } catch (Exception e) {
            //搜索出现异常
            log.error("搜索出现异常!params = {}", params, e);
            return new PageResult();
        }
    }
}

参数封装:

    private Query buildBasicQuery(RequestParams params) {
        // 1.构建BooleanQuery
        BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();

        // 2.关键字搜索
        if (ObjectUtil.isEmpty(params.getKey())) {
            //没有搜索关键词
            boolQueryBuilder.must(builder -> builder.matchAll(m -> m));
        } else {
            boolQueryBuilder.must(builder -> builder.match(m -> m.field("all").query(params.getKey())));
        }

        // 3.城市条件
        if (ObjectUtil.isNotEmpty(params.getCity())) {
            boolQueryBuilder.filter(builder -> builder.term(t -> t.field("city").value(params.getCity())));
        }
        // 4.品牌条件
        if (ObjectUtil.isNotEmpty(params.getBrand())) {
            boolQueryBuilder.filter(builder -> builder.term(t -> t.field("brand").value(params.getBrand())));
        }
        // 5.星级条件
        if (ObjectUtil.isNotEmpty(params.getStarName())) {
            boolQueryBuilder.filter(builder -> builder.term(t -> t.field("starName").value(params.getStarName())));
        }
        // 6.价格
        if (ObjectUtil.isAllNotEmpty(params.getMinPrice(), params.getMaxPrice())) {
            boolQueryBuilder.filter(builder -> builder.range(r -> r.field("price")
                    .gte(JsonData.of(params.getMinPrice())).lte(JsonData.of(params.getMaxPrice()))));
        }
        // 7.构造Query对象
        return new Query.Builder()
                .bool(boolQueryBuilder.build())
                .build();
    }

地理空间查询:

    @Override
    public PageResult search(RequestParams params) {
        //1. 构造搜索对象
        Query query = this.buildBasicQuery(params);

        //2. 计算分页参数
        int size = params.getSize();
        int from = PageUtil.getStart(params.getPage() - 1, size);

        //模拟位置
        params.setLocation("31.03, 121.61");
        try {
            //构造搜索对象
            SearchRequest.Builder searchBuilder = new SearchRequest.Builder();
            searchBuilder.index(INDEX_NAME) //指定索引库
                    .query(query) //指定查询条件
                    .from(from) //设置分页查询参数
                    .trackScores(true) //返回得分值
                    .size(size);

            String location = params.getLocation();
            if (ObjectUtil.isNotEmpty(location)) {
                searchBuilder.sort(s -> s.geoDistance(d -> d.field("location")
                        .location(GeoLocation.of(geo -> geo.text(location)))
                        .order(SortOrder.Asc)
                        .unit(DistanceUnit.Kilometers)));
            }

            //3. 执行搜索
            SearchResponse<HotelDoc> response = this.elasticsearchClient.search(searchBuilder.build(), HotelDoc.class);

            //处理查询结果
            HitsMetadata<HotelDoc> hits = response.hits();
            //数据列表
            List<HotelDoc> hotelDocList = CollStreamUtil.toList(hits.hits(), Hit::source);
            return new PageResult(hits.total().value(), hotelDocList);
        } catch (Exception e) {
            //搜索出现异常
            log.error("搜索出现异常!params = {}", params, e);
            return new PageResult();
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值