Elasticsearch的基本使用

1.必要的配置
@Configuration
@EnableConfigurationProperties(EsProperties.class)
public class EsConfiguration {

@Bean
public ElasticsearchClient esClient(EsProperties esProperties) {
    // Create the low-level client
    RestClient restClient = RestClient.builder(
            new HttpHost(esProperties.getHost(), esProperties.getPort())).build();
    // 创建 ObjectMapper 实例
    ObjectMapper objectMapper = new ObjectMapper();
    // 添加 JavaTimeModule 以支持 LocalDateTime 类型
    objectMapper.registerModule(new JavaTimeModule());

    // Create the transport with a Jackson mapper
    ElasticsearchTransport transport = new RestClientTransport(
            restClient, new JacksonJsonpMapper(objectMapper));


    // And create the API client
    ElasticsearchClient esClient = new ElasticsearchClient(transport);
    return esClient;
}

public class EsProperties {
/**
* es host
/
private String host;
/
*
* es 端口
*/
private Integer port;
host与post可以通过@ConfigurationProperties从配置中获取

1.range查询
public void testRangeQuery() throws IOException {
SearchResponse response = esClient.search(s->
s.index("items")
.query(q->q.range(r->r.field("price").gte(JsonData.of(100000)).lte(JsonData.of(200000))))
, ItemDoc.class);
extracted(response);
}

private static void extracted(SearchResponse<ItemDoc> response) {
    log.info("总共{}条数据", response.hits().total().value());
    List<Hit<ItemDoc>> hits = response.hits().hits();
    hits.forEach(hit->{
        System.out.println(hit.source());
    });
}

2.match查询
public void testMatchQuery() throws IOException {
SearchResponse response = esClient.search(s->
s.index("items")
.query(q->q.match(m->m.field("name").query("健康早餐奶")))
, ItemDoc.class);
extracted(response);
}

3.bool查询
public void testBoolQuery() throws IOException {
SearchResponse response = esClient.search(s->
s.index("items")
.query(q->q.bool(b->b
.must(m->m.match(match->match.field("name").query("手机")))
.mustNot(m->m.range(t->t.field("price").gte(JsonData.of(25000))))
.should(m->m.term(t->t.field("brand").value("小米")))
.should(m->m.term(t->t.field("brand").value("vivo")))
))
, ItemDoc.class);
extracted(response);
}

数据处理extracted:
private static void extracted(SearchResponse response) {
log.info("总共{}条数据", response.hits().total().value());
List<Hit> hits = response.hits().hits();
hits.forEach(hit->{
System.out.println(hit.source());
});
}

multi_match查询
public void testMultiMatchQuery() throws IOException {
SearchResponse response = esClient.search(s->
s.index("items")
.query(q->q.multiMatch(m->m.fields("name","category").query("德国进口牛奶")))
.sort(s1->s1.field(f->f.field("price").order(SortOrder.Desc)))
.sort(s2->s2.field(f->f.field("stock").order(SortOrder.Asc)))
.from(0)
.size(20)
, ItemDoc.class);
extracted(response);
}

term查询
SearchResponse response = esClient.search(s->
s.index("items")
.query(q->q.term(t->t.field("category").value("拉杆箱")))
, ItemDoc.class);
extracted(response);
}

高亮显示
public void testHightLight() throws IOException {
SearchResponse response = esClient.search(s->
s.index("items")
.query(q->q.match(m->m.field("brand").query("小米")))
.highlight(h->h.fields("name",f->f.preTags(" ").postTags("").requireFieldMatch(false)))
, ItemDoc.class);
long total = response.hits().total().value();
log.info("总共{}条数据", total);
List<Hit> hits = response.hits().hits();
for (Hit hit : hits) {
ItemDoc itemDoc = hit.source();
Map<String, List> highlightFields = hit.highlight();
if (highlightFields != null && highlightFields.containsKey("name")) {
List name = highlightFields.get("name");
if(name != null&& name.size() > 0){
itemDoc.setName(name.get(0));
System.out.println(itemDoc);
}
}
}

}

通过Bool为核心的电商平台查询核心功能(加上名字的高亮显示):
public PageDTO search(ItemPageQuery query) throws Exception {
log.info("查询条件为{}",query);
// 分页查询
SearchResponse response = esClient.search(s ->
s.index("items")
.query(q -> q.bool(b -> {
// 检查 key 是否为空
if (StrUtil.isNotBlank(query.getKey())) {
b.must(m -> m.match(match -> match.field("name").query(query.getKey())));
}
// 检查 minPrice 是否有效
if (query.getMinPrice() != null) {
b.must(m -> m.range(t -> t.field("price").gte(JsonData.of(query.getMinPrice()))));
}
// 检查 maxPrice 是否有效
if (query.getMaxPrice() != null) {
b.must(m -> m.range(t -> t.field("price").lte(JsonData.of(query.getMaxPrice()))));
}
// 检查 brand 是否为空
if (StrUtil.isNotBlank(query.getBrand())) {
b.should(m -> m.term(t -> t.field("brand").value(query.getBrand())));
}
// 检查 category 是否为空
if (StrUtil.isNotBlank(query.getCategory())) {
b.should(m -> m.term(t -> t.field("category").value(query.getCategory())));
}
return b;
})).from(0).size(1000).highlight(h -> h.fields("name", f -> f.preTags(" ").postTags("").requireFieldMatch(false)))

            , ItemDoc.class);
    // 封装并返回
    List<Hit<ItemDoc>> hits = response.hits().hits();
    for (Hit<ItemDoc> hit : hits) {
        ItemDoc itemDoc = hit.source();
        Map<String, List<String>> highlightFields = hit.highlight();
        if (highlightFields != null && highlightFields.containsKey("name")) {
            List<String> name = highlightFields.get("name");
            if (name != null && name.size() > 0) {
                itemDoc.setName(name.get(0));
            }
        }
    }
    List<ItemDoc> list = new ArrayList<>();
    if (CollUtils.isNotEmpty(hits)) {
        list = hits.stream().map(Hit::source).collect(Collectors.toList());
    }

    //List<ItemDTO> result = BeanUtil.copyToList(list, ItemDTO.class);
    Page<ItemDoc> pageResult = new Page<>(query.getPageNo(), query.getPageSize());
    System.out.println(response.hits().total().value());
    pageResult.setTotal(response.hits().total().value());
    pageResult.setRecords(list);
    return PageDTO.of(pageResult, ItemDoc.class);
}
posted @ 2025-03-24 20:49  人生何处不青山啊  阅读(24)  评论(0)    收藏  举报