ElasticSearch 7 学习(14)NBA中国官网实战

官方网站:https://china.nba.com/playerindex/

项目搭建

Spring Boot 整合 ElasticSearch 和 MySQL

POM依赖

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

YML依赖

elasticsearch:
  host: localhost
  port: 9200

ElasticSearch配置文件

package com.frame.elasticsearch.config;

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

/**
 * ElasticSearch配置文件
 * ES7使用RestHighLevelClient操作ES
 */
@SpringBootConfiguration
@ConfigurationProperties(prefix = "elasticsearch")
@Data
public class ElasticSearchConfig {
    private String host;
    private Integer port;

    /**
     * 创建RestHighLevelClient 实例
     */
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        HttpHost http = new HttpHost(host, port, "http");
        return new RestHighLevelClient(RestClient.builder(http));
    }
}

ElasticSearch CRUD入门操作

  • 对象转Map工具类
import org.springframework.cglib.beans.BeanMap;

import java.util.HashMap;
import java.util.Map;

public class BeanUtils {
    /**
     * 对象转为Map
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        HashMap<String, Object> map = new HashMap<>();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object o : beanMap.keySet()) {
                if (beanMap.get(o) != null) {
                    map.put(o.toString(), beanMap.get(o));
                }
            }
        }
        return map;
    }
}
  • CRUD 实现方法
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frame.common.entity.NbaPlayer;
import com.frame.common.utils.BeanUtils;
import com.frame.elasticsearch.mapper.NbaPlayerMapper;
import com.frame.elasticsearch.service.NbaPlayerService;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Crazy.X
 * @since 2019-11-10
 */
@Service
public class NbaPlayerServiceImpl implements NbaPlayerService {

    /* ES索引 */
    private final String NBA_INDEX = "nba_latest";

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 添加一条文档
     */
    @Override
    public boolean addPlayer(NbaPlayer player, String id) throws IOException {
        // 获取 IndexRequest
        IndexRequest request = new IndexRequest(NBA_INDEX)
                .id(id)
                .source(BeanUtils.beanToMap(player));
        // 获取 IndexResponse
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(response));
        return false;
    }

    /**
     * 获取一条文档
     */
    @Override
    public Map<String, Object> getPlayer(String id) throws IOException {
        // 获取 GetRequest
        GetRequest getRequest = new GetRequest(NBA_INDEX, id);
        // 获取 GetResponse
        GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        // 返回结果
        return getResponse.getSource();
    }

    /**
     * 更新一条文档
     */
    @Override
    public boolean updatePlayer(NbaPlayer nbaPlayer, String id) throws IOException {
        // 获取 UpdateRequest
        UpdateRequest updateRequest = new UpdateRequest(NBA_INDEX, id)
                .doc(BeanUtils.beanToMap(nbaPlayer));
        // 获取 UpdateResponse
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(update));
        return true;
    }

    /**
     * 删除一条文档
     */
    @Override
    public boolean deletePlayer(String id) throws IOException {
        // 获取 DeleteRequest
        DeleteRequest deleteRequest = new DeleteRequest(NBA_INDEX, id).id(id);
        // 获取 DeleteResponse
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(delete);
        return true;
    }

    /**
     * 删除所有文档
     * 先查询所所有在进行删除
     */
    @Override
    public boolean deleteAllPlayer() throws IOException {
        // 获取 deleteByQueryRequest
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(NBA_INDEX);
        // 获取 BulkByScrollResponse
        BulkByScrollResponse bulkByScrollResponse = restHighLevelClient.deleteByQuery(
                deleteByQueryRequest,
                RequestOptions.DEFAULT
        );
        return true;
    }
}
  • CRUD 测试类
import com.frame.common.entity.NbaPlayer;
import com.frame.elasticsearch.service.NbaPlayerService;
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;

import java.io.IOException;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class NbaPlayerServiceImplTest {

    @Autowired
    NbaPlayerService nbaPlayerService;

    @Test
    public void addPlayer() throws IOException {
        NbaPlayer nbaPlayer = new NbaPlayer()
                .setId(999)
                .setDisplayName("姚明");
        boolean result = nbaPlayerService.addPlayer(nbaPlayer, "999");
    }

    @Test
    public void getPlayer() throws IOException {
        Map<String, Object> player = nbaPlayerService.getPlayer("999");
        System.out.println(player);
    }

    @Test
    public void updatePlayer() throws IOException {
        NbaPlayer nbaPlayer = new NbaPlayer()
                .setId(999)
                .setDisplayName("易建联");
        boolean result = nbaPlayerService.updatePlayer(nbaPlayer, "999");
    }

    @Test
    public void deletePlayer() throws IOException {
        boolean result = nbaPlayerService.deletePlayer("999");
    }

    @Test
    public void deleteAllPlayer() throws IOException {
        boolean result = nbaPlayerService.deleteAllPlayer();
    }
}

接口开发

  • Result结果集Vo
import com.frame.common.enums.ResultEnum;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 结果封装Vo
 */
@Data
@AllArgsConstructor
public class Result<T> {

    private Integer code;
    private String msg;
    private T data;

    public static <T> Result success() {
        return success(null);
    }

    public static <T> Result success(T data) {
        return success(ResultEnum.SUCCESS.getCode(), data);
    }

    public static <T> Result success(Integer code, T data) {
        return success(code, ResultEnum.SUCCESS.getMsg(), data);
    }

    public static <T> Result success(String msg, T data) {
        return success(ResultEnum.SUCCESS.getCode(), msg, data);
    }

    public static <T> Result success(Integer code, String msg, T data) {
        return new Result<T>(code, msg, data);
    }

    public static <T> Result fail() {
        return fail(ResultEnum.FAIL.getCode());
    }

    public static <T> Result fail(Integer code) {
        return fail(code, ResultEnum.FAIL.getMsg());
    }

    public static <T> Result fail(String msg) {
        return fail(ResultEnum.FAIL.getCode(), msg);
    }

    public static <T> Result fail(Integer code, String msg) {
        return success(code, msg, null);
    }
}
  • 结果集对应的枚举
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * Result结果集枚举类
 */
@Getter
@AllArgsConstructor
public enum ResultEnum {

    SUCCESS(200, "操作成功"),
    FAIL(400,"操作失败")
    ;
    private Integer code;
    private String msg;
}

将数据库数据导入到 ElasticSearch

  • Controller层
/**
 * 从mysql导入数据到es
 */
@GetMapping("/import")
public Result importAllPlayer() {
    try {
        nbaPlayerService.importAllPlayer();
        return Result.success("数据导入成功");
    } catch (IOException e) {
        log.error("ElasticSearch导入数据失败");
        e.printStackTrace();
        return Result.fail("ElasticSearch导入数据失败");
    }
}
  • Service层
/**
 * 从mysql导入数据到es
 */
@Override
@Transactional
public boolean importAllPlayer() throws IOException {
    // 查询所有数据,这里使用MybatisPlus不作解释
    List<NbaPlayer> nbaPlayers = list();
    for (NbaPlayer e : nbaPlayers) {
        // 此处调用的增加文档方法
        addPlayer(e, String.valueOf(e.getId()));
    }
    return true;
}

通过姓名查找球员

  • Controller层
/**
 * 通过姓名查找球员
 */
@GetMapping("/searchMatch")
public Result searchMatch(@RequestParam("key") String key,
                          @RequestParam("val") String val,
                          @RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
                          @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit) {
    List<NbaPlayer> nbaPlayers = null;
    try {
        nbaPlayers = nbaPlayerService.searchTerm(key, val, page, limit);
    } catch (IOException e) {
        log.error("searchMatch失败,参数[key={}]][val={}]]", key, val);
        e.printStackTrace();
    }
    return Result.success(nbaPlayers);
}
  • service层
/**
 * 通过姓名查找球员
 */
@Override
public List<NbaPlayer> searchMatch(String key, String val, Integer page, Integer limit) throws IOException {
    // 获取 SearchRequest
    SearchRequest searchRequest = new SearchRequest(NBA_INDEX);
    // 创建 SearchSourceBuilder 用于查询语句
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder
            // 查询 通过match查询 key 字段名称 val 字段值
            .query(QueryBuilders.termQuery(key, val))
            // 起始页
            .from(page)
            // 显示条数
            .size(limit);
    // 设置 请求源 理解为设置查询语句
    searchRequest.source(searchSourceBuilder);
    // 获取 SearchResponse 查询数据
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    // 获取碰撞之后的结果 (固定写法)
    SearchHit[] hits = searchResponse.getHits().getHits();
    // 进行对象转换并返回
    return Stream.of(hits)
            .map(e -> JSON.parseObject(e.getSourceAsString(), NbaPlayer.class))
            .collect(Collectors.toList());
}

通过国家或者球队查询球员

  • Controller层
/**
 * 通过国家或者球队查询球员
 */
@GetMapping("/searchTerm")
public Result searchTerm(@RequestParam(value = "country", required = false) String country,
                         @RequestParam(value = "teamName", required = false) String teamName,
                         @RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
                         @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit) {
    List<NbaPlayer> nbaPlayers = null;
    try {
        // 路由选择国家 或者 球队
        if (StringUtils.isNotBlank(country)) {
            nbaPlayers = nbaPlayerService.searchTerm("country", country, page, limit);
        } else {
            nbaPlayers = nbaPlayerService.searchTerm("teamName", teamName, page, limit);
        }
    } catch (IOException e) {
        log.error("searchTerm失败,参数[country={}]][teamName={}]]", country, teamName);
        e.printStackTrace();
    }
    return CollectionUtils.isNotEmpty(nbaPlayers) ? Result.success(nbaPlayers) : Result.success();
}
  • Service层
/**
 * 通过国家或者球队查询球员
 */
@Override
public List<NbaPlayer> searchTerm(String key, String val, Integer page, Integer limit) throws IOException {
    // 获取 SearchRequest
    SearchRequest searchRequest = new SearchRequest(NBA_INDEX);
    // 创建 SearchSourceBuilder 用于查询语句
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder
            // 查询 通过match查询 key 字段名称 val 字段值
            .query(QueryBuilders.termQuery(key, val))
            // 起始页
            .from(page)
            // 显示条数
            .size(limit);
    // 设置 请求源 理解为设置查询语句
    searchRequest.source(searchSourceBuilder);
    // 获取 SearchResponse 查询数据
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    // 获取碰撞之后的结果 (固定写法)
    SearchHit[] hits = searchResponse.getHits().getHits();
    // 进行对象转换并返回
    return Stream.of(hits)
            .map(e -> JSON.parseObject(e.getSourceAsString(), NbaPlayer.class))
            .collect(Collectors.toList());
}

通过姓名字母查找球员

  • Controller层
/**
 * 通过姓名字母查找球员
 */
@GetMapping("/searchPrefix")
public Result searchPrefix(@RequestParam(value = "prefix", required = false, defaultValue = "A") String prefix,
                           @RequestParam(value = "page", required = false, defaultValue = "0") Integer page,

                           @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit) {
    List<NbaPlayer> nbaPlayers = null;
    try {
        nbaPlayers = nbaPlayerService.searchPrefix(prefix, page, limit);
    } catch (IOException e) {
        log.error("searchPrefix失败,参数[prefix={}]]", prefix);
        e.printStackTrace();
    }
    return CollectionUtils.isNotEmpty(nbaPlayers) ? Result.success(nbaPlayers) : Result.success();
}
  • Service层
/**
 * 通过姓名字母查找球员
 */
@Override
public List<NbaPlayer> searchPrefix(String prefix, Integer page, Integer limit) throws IOException {
    // 获取 SearchRequest
    SearchRequest searchRequest = new SearchRequest(NBA_INDEX);
    // 创建 SearchSourceBuilder 用于查询语句
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder
            // 查询 通过prefix查询 displayNameEn.keyword 名字字段 prefix 前缀字母
            .query(QueryBuilders.prefixQuery("displayNameEn.keyword", prefix))
            // 起始页
            .from(page)
            // 显示条数
            .size(limit);
    // 设置 请求源 理解为设置查询语句
    searchRequest.source(searchSourceBuilder);
    // 获取 SearchResponse 查询数据
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    // 获取碰撞之后的结果 (固定写法)
    SearchHit[] hits = searchResponse.getHits().getHits();
    // 进行对象转换并返回
    return Stream.of(hits)
            .map(e -> JSON.parseObject(e.getSourceAsString(), NbaPlayer.class))
            .collect(Collectors.toList());
}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/12/elasticsearch-7-learning-nba-china-official-website-practice/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
ElasticSearch 7 学习(14)NBA中国官网实战
官方网站:https://china.nba.com/playerindex/ 项目搭建 Spring Boot 整合 ElasticSearch 和 MySQL POM依赖 <!-- elasticsearch-rest-high-level-client ……
<<上一篇
下一篇>>
文章目录
关闭
目 录