ES普通用法(模糊查询、高亮、分类、排序、批量添加)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

仅个人笔记!


提示:以下是本篇文章正文内容,下面案例可供参考

一、ES是什么?

ES(Elasticsearch)是一个基于RESTful web接口并且构建在Apache Lucene之上的开源分布式搜索引擎。它不仅是一个功能强大的搜索引擎,还具备分布式文档数据库的特性,能够处理PB级的数据

二、使用步骤

1.依赖

代码如下(示例):

<!-- es -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

2.配置类

代码如下(示例):

@Configuration
@ConfigurationProperties(prefix = "es")
@Data
public class InitEsRes {
    private String host;
    private int port;
    private String scheme;

    @Bean
    public RestHighLevelClient
    restHighLevelClient(){
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(host,port,scheme))
        );
    }
}
@Configuration
@ConfigurationProperties(prefix = "es")
@Data
public class InitESRestHighLevelClient {

    /**
     * es服务 地址
     */
    private String host;

    /**
     * 端口
     */
    private int port;

    /**
     * 请求方式
     */
    private String scheme;

    /**
     * 构建 RestHighLevelClient 用来做 es 操作
     * @return
     */
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(host, port, scheme))
        );
    }

}

3.实现方法(模糊查询、高亮、分类、排序、批量添加)

代码如下(示例):

@Service
@Slf4j
public class IESSpuInfoServiceImpl implements IESSpuInfoService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    private static final String INDEX_NAME = "product_info";
    private static final String NAME = "spuName";

    @Override
    public List<PmsSpuInfoVO> esSpuInfoList(String keywords) {
        ArrayList<PmsSpuInfoVO> list = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchRequest.source(searchSourceBuilder);
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (StringUtils.isNotBlank(keywords)){
            boolQueryBuilder.must(QueryBuilders.matchQuery(NAME,keywords));
        }
        searchSourceBuilder.highlighter(
                new HighlightBuilder()
                        .field(NAME)
                        .preTags("<span style = \"color:red\">")
                        .postTags("</span>")
        );

        // 分类
        TermsAggregationBuilder aggregation = AggregationBuilders.terms("brand_id").field("brandId");
        searchSourceBuilder.aggregation(aggregation);

        // 排序
        searchSourceBuilder.sort(SortBuilders.fieldSort("lastUpdatedTime").order(SortOrder.ASC));

        searchSourceBuilder.query(boolQueryBuilder);
        try {
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = searchResponse.getHits();
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit searchHit : searchHits) {
                String sourceAsString = searchHit.getSourceAsString();
                PmsSpuInfoVO warranty = JSONObject.parseObject(sourceAsString, PmsSpuInfoVO.class);
                Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                if (highlightFields!=null){
                    HighlightField highlightField = highlightFields.get(NAME);
                    if (highlightField!=null){
                        Text[] fragments = highlightField.getFragments();
                        StringBuffer stringBuffer = new StringBuffer();
                        for (Text fragment : fragments) {
                            stringBuffer.append(fragment);
                        }
                        warranty.setSpuName(stringBuffer.toString());
                    }
                }
                list.add(warranty);

            }
        }catch (Exception e){
            log.info("错误:",e);
        }
        return list;
    }

    @Override
    public void updateProductInfo(List<PmsSpuInfoVO> updatedProducts) {
        BulkRequest bulkRequest = new BulkRequest();
        updatedProducts.forEach(pmsSpuInfoVO -> {
            bulkRequest.add(
                    new IndexRequest(INDEX_NAME)
                            .id(pmsSpuInfoVO.getId().toString())
                            .source(JSON.toJSONString(pmsSpuInfoVO), XContentType.JSON));
        });
        try {
            BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println(bulkResponse.status());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}


拓展

(定时任务)根据时间判断通过mq将数据存es列表

1.依赖

代码如下(示例):

<!-- rabbitMQ -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.配置类

代码如下(示例):

package com.shop.pms.config;

import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqConfig {
    // 消息转换配置
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public DirectExchange productExchange() {
        // 创建一个名为productName的直连交换机,并设置为持久化
        return new DirectExchange("productName", true, false);
    }
}

package com.shop.pms.config;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * rabbitAdmin 配置类 用来构建 RabbitAdmin
 */
@Configuration
public class RabbitAdminConfig {

    @Value("${spring.rabbitmq.host}")
    private String host;
    @Value("${spring.rabbitmq.username}")
    private String username;
    @Value("${spring.rabbitmq.password}")
    private String password;
    @Value("${spring.rabbitmq.virtualHost}")
    private String virtualhost;

    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(host);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualhost);
        // 设置消息发送确认
        connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        connectionFactory.setPublisherReturns(true);
//我们将填充好的 cachingConnectionFactory 实例进行返回,以初始化完成 RabbitMQ 客户端连接
        return connectionFactory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }


}

package com.shop.pms.config;

import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 消息发送到队列的确认
 */
@Component
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct // @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
    public void init() {
        rabbitTemplate.setReturnsCallback(this);
    }

    /**
     * 消息发送到 队列失败的时候执行
     * @param returnedMessage the returned message and metadata.
     */
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        System.out.println("消息" + returnedMessage.getMessage().toString() + "被交换机" + returnedMessage.getExchange() + "回退!"
                + "退回原因为:" + returnedMessage.getReplyText());
        // TODO 回退了所有的信息,可做补偿机制
    }
}

3.实现方法

代码如下(示例):

@Override
public List<PmsSpuInfoVO> productInfoList() {
    List<PmsSpuInfoVO> productInfoList = mainPageMapper.productInfoList();
    // 计算30分钟前的时间
    Date thirtyMinutesAgo = new Date(System.currentTimeMillis() - 30 * 60 * 1000);
    // 过滤最近30分钟内更新的产品
    List<PmsSpuInfoVO> updatedProducts = productInfoList.stream()
            .filter(product -> product.getLastUpdatedTime().after(thirtyMinutesAgo))
            .collect(Collectors.toList());
    // 发送RabbitMQ消息
    if (!updatedProducts.isEmpty()) {
        log.info("发送数据几条:{}", updatedProducts.size());
        rabbitTemplate.convertAndSend("productSpuInfo", updatedProducts);
    } else {
        log.info("没有产品在最近30分钟内更新");
    }
    return productInfoList;
}

@Component
@Slf4j
public class MessageConsumer {
    @Autowired
    private IESSpuInfoService esSpuInfoService;

    @RabbitListener(queuesToDeclare =@Queue("productSpuInfo"))
    public void handleProductMessage(List<PmsSpuInfoVO> pmsSpuInfoVOList) {
        if (pmsSpuInfoVOList == null || pmsSpuInfoVOList.isEmpty()) {
            log.warn("Received an empty or null list of product info. Skipping...");
            return;
        }

        try {
            log.info("Starting to update product info for {} items", pmsSpuInfoVOList.size());
            esSpuInfoService.updateProductInfo(pmsSpuInfoVOList);
            log.info("Successfully updated product info for {} items", pmsSpuInfoVOList.size());
        } catch (Exception e) {
            log.error("Error updating product info", e);
            // 根据业务需求,可以选择重新抛出异常或者进行其他补偿措施
            throw new RuntimeException("Failed to update product info", e);
        }
    }

}

4.定时任务实现方法

代码如下(示例):

@Component
@Slf4j
public class SyncService {

    @Autowired
    private IMainPageServiceImpl iMainPageService;


//    @Scheduled(fixedRate = 100) // 测试使用
    @Scheduled(fixedRate = 1800000) // 每30分钟执行一次
    public void syncDataToES() {
        List<PmsSpuInfoVO> productInfoList = iMainPageService.productInfoList();
        log.info(productInfoList.toString());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值