Solo  当前访客:3 开始使用

JAVA日知录

一个关注| Java | Spring Boot | Spring Cloud | 干货分享的博客网站

AOP 更新 ElasticSearch 索引---导入ElasticSearch

2020-04-23 14:29:14 shuikan95
0  评论    119  浏览

TiDB test库,item表 导入ElasticSearch

  • 启动 ElasticSearch 和 Kibana
root@jazz-pc:/opt# docker ps --format "table {{.Names}} ------> {{.Ports}}" | grep es
es ------> 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp
root@jazz-pc:/opt# docker ps --format "table {{.Names}} ------> {{.Ports}}" | grep kibana
kibana ------> 0.0.0.0:5601->5601/tcp
  • 创建索引,使用 Chrome elasticsearch-head 插件

image.png

ElasticSearch 相关类

  • ESClientConfig
package com.lab.es.demo.config;

import com.lab.es.demo.utils.ESconst;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ESClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        HttpHost host = new HttpHost(ESconst.hostname, ESconst.port, HttpHost.DEFAULT_SCHEME_NAME);

        RestClientBuilder builder = RestClient.builder(host);
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(ESconst.username, ESconst.password));
        builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
        RestHighLevelClient restClient = new RestHighLevelClient(builder);
        return restClient;
    }
}
  • ESconst
package com.lab.es.demo.utils;

import org.apache.http.HttpHost;

public class ESconst {
    public static final String hostname = "192.168.1.6";
    public static final Integer port = 9200;
    public static final String scheme = HttpHost.DEFAULT_SCHEME_NAME;
    public static final String username = "elastic";
    public static final String password = "Aa123456";
}
  • ItemService#databaseToES
package com.lab.es.demo.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lab.es.demo.annotation.IndexHandle;
import com.lab.es.demo.common.ResFactory;
import com.lab.es.demo.common.ResPaging;
import com.lab.es.demo.dto.SearchItemDTO;
import com.lab.es.demo.dto.UpdateItemDTO;
import com.lab.es.demo.entity.Item;
import com.lab.es.demo.mapper.ItemMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
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.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchPhrasePrefixQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ItemService {
    private static final String INDEX_NAME = "tmall_items";
    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public Boolean databaseToES() throws Exception {
        QueryWrapper<Item> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "item_name", "master_pic", "item_price", "tbk_link", "shop_name", "monthly_sales");

        List<Item> items = itemMapper.selectList(queryWrapper);

        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");

        Item item = null;
        for (int i = 0; i < items.size(); i++) {
            item = items.get(i);
            bulkRequest.add(
                    new IndexRequest(INDEX_NAME).id(item.getId()).source(JSON.toJSONString(item), XContentType.JSON)
            );
        }

        BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !response.hasFailures();
    }

    public ResPaging searchPageHighlight(SearchItemDTO searchItemDTO) throws IOException {
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        sourceBuilder.from((searchItemDTO.getPageNo() - 1) * searchItemDTO.getPageSize());
        sourceBuilder.size(searchItemDTO.getPageSize());

        MatchPhrasePrefixQueryBuilder matchPhrasePrefixQueryBuilder = QueryBuilders.matchPhrasePrefixQuery("itemName", searchItemDTO.getKeyword());

        sourceBuilder.query(matchPhrasePrefixQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        String sort = searchItemDTO.getSort();
        if (sort.equals("itemPriceUp")) {
            sourceBuilder.sort(new FieldSortBuilder("itemPrice").order(SortOrder.ASC));
        } else if (sort.equals("itemPriceDown")) {
            sourceBuilder.sort(new FieldSortBuilder("itemPrice").order(SortOrder.DESC));
        } else if (sort.equals("monthlySalesUp")) {
            sourceBuilder.sort(new FieldSortBuilder("monthlySales").order(SortOrder.ASC));
        } else if (sort.equals("monthlySalesDown")) {
            sourceBuilder.sort(new FieldSortBuilder("monthlySales").order(SortOrder.DESC));
        }

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("itemName");
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

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

        List<Map<String, Object>> list = new ArrayList<>();
        SearchHits searchHits = searchResponse.getHits();
        int totalHits = (int) searchHits.getTotalHits().value;

        for (SearchHit hit : searchHits.getHits()) {
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField itemName = highlightFields.get("itemName");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if (itemName != null) {
                Text[] fragments = itemName.fragments();
                String n_itemName = "";
                for (Text text : fragments) {
                    n_itemName += text;
                }
                sourceAsMap.put("itemNameHighlight", n_itemName);
            }
            list.add(sourceAsMap);
        }

        return ResFactory.getInstance().getResPaging(list, searchItemDTO.getPageNo(), searchItemDTO.getPageSize(), totalHits);
    }

    @IndexHandle(desc = "异步更新ElasticSearch索引")
    public int updateItem(UpdateItemDTO updateItemDTO) throws Exception {
        if (StringUtils.isEmpty(updateItemDTO.getId())) {
            throw new Exception("更新商品,ItemId 不能为空");
        }

        try {
            Item item = itemMapper.selectById(updateItemDTO.getId());
            item.setItemName(updateItemDTO.getItemName());
            item.setItemPrice(updateItemDTO.getItemPrice());
            item.setMonthlySales(updateItemDTO.getMonthlySales());
            return itemMapper.updateById(item);
        } catch (Exception e) {
            throw new Exception("更新商品发生错误," + e.getMessage());
        }
    }
}

导入 ElasticSearch

  • ItemTest
package com.lab.es.demo;

import com.lab.es.demo.service.ItemService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BookESApplication.class)
public class ItemTest {
    @Autowired
    private ItemService itemService;

    @Test
    public void databaseToES() throws Exception {
        Boolean result = itemService.databaseToES();
        log.info("databaseToES:" + result.toString());
    }
}
  • 执行测试
mvn test -Dtest=com.lab.es.demo.ItemTest#databaseToES

image.png

  • elasticsearch-head 查看索引数据

image.png

  • Kibana 查看索引结构 和 分页搜索并排序

image.png

image.png

GET tmall_items/_mapping

GET tmall_items/_search 
{
  "query": {
    "match_phrase_prefix": {
      "itemName": "糕点"
    }
  },
  "sort": [
    {
      "itemPrice": {
        "order": "desc"
      }
    }
  ],
  "from": 20,
  "size": 10
}


标题:AOP 更新 ElasticSearch 索引---导入ElasticSearch
作者:shuikan95
地址:http://www.javadaily.cn/articles/2020/04/22/1587550493800.html

, ,

发表评论


TOP