ES客户端索引相关操作
  TEZNKK3IfmPf 2023年11月13日 15 0
├─config      # 配置文件
├─controller # 控制器
├─entity # 实体映射
│ └─response # 响应实体
└─service # 相关业务

在 response 包下,新建两个类,分别是 ResultCode(interface), ResponseResult.java:

ResultCode.java:

/**
* @author BNTang
*/
public interface ResultCode {
/**
* 成功状态码
*/
Integer SUCCESS = 20000;
/**
* 失败的状态码
*/
Integer ERROR = 20001;
}

ResponseResult.java:

@Data
public class ResponseResult {
private ResponseResult() {
}

@ApiModelProperty(value = "是否成功")
private Boolean success;

@ApiModelProperty(value = "状态码")
private Integer code;

@ApiModelProperty(value = "返回消息")
private String message;

@ApiModelProperty(value = "返回的数据")
private Map<String, Object> RESPONSE_DATA_MAP = new HashMap<>();

/**
* 提供工具方法
*/
public static ResponseResult ok() {
ResponseResult responseResult = new ResponseResult();
responseResult.setSuccess(true);
responseResult.setCode(ResultCode.SUCCESS);
responseResult.setMessage("成功");
return responseResult;
}

public static ResponseResult error() {
ResponseResult responseResult = new ResponseResult();
responseResult.setSuccess(false);
responseResult.setCode(ResultCode.ERROR);
responseResult.setMessage("失败");
return responseResult;
}

public ResponseResult success(Boolean success) {
this.setSuccess(success);
return this;
}

public ResponseResult message(String message) {
this.setMessage(message);
return this;
}

public ResponseResult code(Integer code) {
this.setCode(code);
return this;
}

public ResponseResult data(String key, Object value) {
this.RESPONSE_DATA_MAP.put(key, value);
return this;
}

public ResponseResult data(Map<String, Object> map) {
this.setRESPONSE_DATA_MAP(map);
return this;
}
}

然后接下来就可以来看本文需要介绍的索引相关的操作内容了:

索引操作

查看索引是否存在

首先在 service 包当中新建一个 IElasticSearchService.java 接口,在当中添加一个判断索引是否存在的约束方法如下:

/**
* @author BNTang
* @version V1.0
* @project SpringBoot-ElasticSearch-Pro
* @date Created in 2022/3/5 /005 18:41
* @description elasticsearch 接口
**/
public interface IElasticSearchService {
/**
* 查看索引是否存在
*
* @param indexName 索引名称
* @return boolean true,代表存在,false,代表不存在
*/
boolean seeIndexIsNoExists(String indexName);
}

还是在 service 包当中创建所对应的实现类来实现这个判断索引是否存在的方法, 新建一个 ElasticSearchServiceImpl.java:

/**
* @author BNTang
* @version V1.0
* @project SpringBoot-ElasticSearch-Pro
* @date Created in 2022/3/5 /005 18:45
* @description
**/
@Service
public class ElasticSearchServiceImpl implements IElasticSearchService {
private final Log logger = LogFactory.getLog(ElasticSearchServiceImpl.class);

private ElasticsearchClient elasticsearchClient;

@Autowired
public void setElasticsearchClient(ElasticsearchClient elasticsearchClient) {
this.elasticsearchClient = elasticsearchClient;
}

@Override
public boolean seeIndexIsNoExists(String indexName) {
ExistsRequest existsRequest = new ExistsRequest.Builder().index(indexName)
.build();

try {
BooleanResponse booleanResponse = this.elasticsearchClient.indices()
.exists(existsRequest);
return booleanResponse.value();
} catch (IOException e) {
logger.error("see Index Is No Exists error", e);
}

return false;
}
}

然后,在 controller 包当中创建一个控制器用来测试用,ElasticSearchController.java:

/**
* @author BNTang
* @version V1.0
* @project SpringBoot-ElasticSearch-Pro
* @date Created in 2022/3/5 /005 18:48
* @description
**/
@Api("ElasticSearch Api Controller")
@RequestMapping("elasticSearch-controller")
@RestController
public class ElasticSearchController {

private ElasticSearchServiceImpl elasticSearchService;

@Autowired
public void setElasticSearchService(ElasticSearchServiceImpl elasticSearchService) {
this.elasticSearchService = elasticSearchService;
}

@ApiOperation("查看索引是否存在")
@GetMapping("seeIndexIsNoExists")
public boolean seeIndexIsNoExists(String indexName) {
return this.elasticSearchService.seeIndexIsNoExists(indexName);
}
}

然后就是启动工程,访问 swagger,进行接口调试即可,这一步博主不贴出来了自行测试。

创建索引

在 IElasticSearchService.java 当中添加如下约束方法:

/**
* 创建索引
*
* @param indexName 索引名称
* @param numOfShards 分片数
* @param properties 属性
* @return boolean true,代表创建成功,false,代表创建失败
*/
boolean createIndex(String indexName, int numOfShards, Map<String, Property> properties);

在 ElasticSearchServiceImpl.java 实现类当中进行实现:

@Override
public boolean createIndex(String indexName, int numOfShards, Map<String, Property> properties) {
// 创建的映射处理
TypeMapping typeMapping = new TypeMapping.Builder()
.properties(properties)
.build();

IndexSettings indexSettings = new IndexSettings.Builder()
.numberOfShards(String.valueOf(numOfShards))
.build();

CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder()
.index(indexName)
.mappings(typeMapping)
.settings(indexSettings)
.build();

try {
return Optional
.ofNullable(this.elasticsearchClient.indices().create(createIndexRequest).acknowledged())
.orElse(Boolean.FALSE);
} catch (IOException e) {
logger.error("create Index error", e);
}

return false;
}

控制器:

@ApiOperation("创建索引")
@GetMapping("createIndex")
public ResponseResult createIndex(String indexName) {
Map<String, Property> propertyMap = new HashMap<>();
propertyMap.put("id", new Property(new LongNumberProperty.Builder().index(true).store(true).build()));
propertyMap.put("name", new Property(new TextProperty.Builder().index(true).analyzer("ik_max_word").store(true).build()));

if (this.elasticSearchService.createIndex(indexName, 1, propertyMap)) {
return ResponseResult.ok();
}
return ResponseResult.error();
}

然后就是启动工程,访问 swagger,进行接口调试即可,这一步博主不贴出来了自行测试。

删除索引

接口:

/**
* 删除索引
*
* @param indexNameList 索引名称列表
* @return boolean
*/
boolean deleteIndex(List<String> indexNameList);

实现类:

@Override
public boolean deleteIndex(List<String> indexNameList) {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder()
.index(indexNameList)
.build();

try {
return this.elasticsearchClient.indices()
.delete(deleteIndexRequest).acknowledged();
} catch (IOException e) {
logger.error("delete Index error", e);
}

return false;
}

控制器:

@ApiOperation("删除索引")
@PostMapping("deleteIndex")
public ResponseResult deleteIndex(@RequestParam List<String> indexNameList) {
if (this.elasticSearchService.deleteIndex(indexNameList)) {
return ResponseResult.ok();
}
return ResponseResult.error();
}

根据 ID 查询(批量OR单个)

更改 IElasticSearchService.java 接口新增泛型:

public interface IElasticSearchService<T>

然后在新增两个查询数据的方法约束:

/**
* 根据id获取文档
*
* @param index index
* @param id id
* @param clazz clazz 把查询的结果封装成对象的实体
* @return T
*/
T getById(String index, String id, Class<T> clazz);

/**
* 根据id列表获取文档
*
* @param index index
* @param idList id
* @param clazz clazz
* @return List<T>
*/
List<T> getByIdList(String index, List<String> idList, Class<T> clazz);

修改 ElasticSearchServiceImpl.java 实现类,也需要添加所对应的泛型:

public class ElasticSearchServiceImpl<T> implements IElasticSearchService<T>

实现根据ID查询的业务方法,可以批量也可以单个:

@Override
public T getById(String index, String id, Class<T> clazz) {
GetRequest getRequest = new GetRequest.Builder()
.index(index)
.id(id)
.build();
try {
return this.elasticsearchClient.get(getRequest, clazz)
.source();
} catch (IOException e) {
logger.error("get By Id error", e);
}
return null;
}

@Override
public List<T> getByIdList(String index, List<String> idList, Class<T> clazz) {
try {
List<T> tList = new ArrayList<>(idList.size());
for (String id : idList) {

GetRequest getRequest = new GetRequest.Builder()
.index(index)
.id(id)
.build();

T source = this.elasticsearchClient.get(getRequest, clazz)
.source();

tList.add(source);
}

return tList;
} catch (IOException e) {
logger.error("get By Id List error", e);
}
return null;
}

然后在控制器调用之前首先在新建一个实体类用来封装从ES当中查询出来的数据新建 Goods.java:

/**
* @author BNTang
* @version V1.0
* @project SpringBoot-ElasticSearch-Pro
* @date Created in 2022/4/3 /003 23:20
* @description
**/
@Data
public class Goods implements Serializable {
/**
* id
*/
private String id;
/**
* 名字
*/
private String name;
/**
* 价格
*/
private BigDecimal price;
/**
* 描述
*/
private String description;
/**
* 创建日期
*/
private String create_date;
}

修改控制器进行使用,测试一下根据 ID 查询出来的结果和批量的接口即可,这里博主不再赘述,只是贴出所对应的控制器代码,修改 ElasticSearchController.java:

private ElasticSearchServiceImpl<Goods> elasticSearchService;

@Autowired
public void setElasticSearchService(ElasticSearchServiceImpl<Goods> elasticSearchService) {
this.elasticSearchService = elasticSearchService;
}
@ApiOperation(value = "根据id获取文档数据")
@GetMapping("/api/v1/getById/{index}/{id}")
public ResponseResult getById(@PathVariable String index, @PathVariable String id) {
return ResponseResult.ok().data("goods", this.elasticSearchService.getById(index, id, Goods.class));
}

@ApiOperation(value = "根据id数组获取文档数据")
@PostMapping("/api/v1/getByIdList")
public ResponseResult getByIdList(@RequestParam(value = "ids") List<String> ids,
@RequestParam(value = "index") String index) {
return ResponseResult.ok().data("goods", this.elasticSearchService.getByIdList(index, ids, Goods.class));
}

ES客户端索引相关操作

分页查询

修改接口添加分页查询约束方法:

/**
* 分页查询
*
* @param index index
* @param pageNo pageNo
* @param pageSize pageSize
* @param clazz clazz
* @return 查询结果
*/
List<T> searchByPages(String index, Integer pageNo, Integer pageSize, Class<T> clazz);

实现类:

@Override
public List<T> searchByPages(String index, Integer pageNo, Integer pageSize, Class<T> clazz) {
SearchRequest searchRequest = new SearchRequest.Builder()
.index(Collections.singletonList(index))
.from(pageNo)
.size(pageSize)
.build();

List<T> res = new ArrayList<>();

try {
SearchResponse<T> searchResponse = this.elasticsearchClient.search(searchRequest, clazz);
HitsMetadata<T> hitsMetadata = searchResponse.hits();
hitsMetadata.hits().forEach(action -> res.add(action.source()));
return res;
} catch (IOException e) {
logger.error("search By Pages error", e);
}

return null;
}

控制器:

@ApiOperation(value = "分页查询文档")
@PostMapping("/getAll")
public ResponseResult getAll(String index, int pageNo, int pageSize) {
return ResponseResult.ok().data("goods", this.elasticSearchService.searchByPages(index, pageNo, pageSize, Goods.class));
}

分页条件查询

接口:

/**
* 分页条件查询
*
* @param index index
* @param pageNo 当前页
* @param pageSize 每页多少条数据
* @param clazz clazz 封装的实现
* @return 查询结果
*/
List<T> searchByQuery(String index, String queryString, Integer pageNo, Integer pageSize, Class<T> clazz);

实现类:

@Override
public List<T> searchByQuery(String index, String queryString, Integer pageNo, Integer pageSize, Class<T> clazz) {
// 1.构建查询的对象
QueryStringQuery stringQuery = new QueryStringQuery.Builder()
.fields("name", "description")
.query(queryString)
.build();

Query query = new Query.Builder()
.queryString(stringQuery)
.build();

// 2.搜索
SearchRequest searchRequest = new SearchRequest.Builder()
.index(index)
.from(pageNo)
.size(pageSize)
.query(query)
.build();

try {
return this.elasticsearchClient.search(searchRequest, clazz)
.hits().hits().stream()
.map(Hit::source)
.collect(Collectors.toList());
} catch (IOException e) {
logger.error("search By Query error", e);
}
return null;
}

控制器:

@ApiOperation(value = "分页条件查询")
@PostMapping("/querySearch")
public ResponseResult getAll(String index, String queryString, Integer pageNo, Integer pageSize) {
return ResponseResult.ok().data("goods", this.elasticSearchService.searchByQuery(index, queryString, pageNo, pageSize, Goods.class));
}

ES客户端索引相关操作

分页条件查询高亮

接口:

/**
* 分页条件高亮查询
*
* @param index index
* @param pageNo 当前页
* @param pageSize 每页多少条数据
* @param clazz clazz 封装的实现
* @return 查询结果
*/
List<T> searchByQueryHighlight(String index, String queryString, Integer pageNo, Integer pageSize, Class<T> clazz);

实现类:

@Override
public List<T> searchByQueryHighlight(String index, String queryString, Integer pageNo, Integer pageSize, Class<T> clazz) {
// 1.构建查询的对象
QueryStringQuery stringQuery = new QueryStringQuery.Builder()
.fields("name", "description")
.query(queryString)
.build();

Query query = new Query.Builder()
.queryString(stringQuery)
.build();

// 高亮显示
HighlightField highlightField = new HighlightField.Builder()
.matchedFields("name")
.preTags("<span style=\"color:red\">")
.postTags("</span>")
.build();

Highlight highlight = new Highlight.Builder()
.fields("name", highlightField)
.requireFieldMatch(false)
.build();

// 2.搜索请求
SearchRequest searchRequest = new SearchRequest.Builder()
.index(index)
.from(pageNo)
.size(pageSize)
.query(query)
.highlight(highlight)
.build();

try {
return this.elasticsearchClient.search(searchRequest, clazz)
.hits()
.hits()
.stream()
.map(mapper -> {
String name = mapper.highlight()
.get("name")
.get(0);

Goods goods = (Goods) mapper.source();
Goods anElse = Optional.ofNullable(goods)
.orElse(new Goods());
anElse.setName(name);
return mapper.source();
}).collect(Collectors.toList());
} catch (IOException e) {
logger.error("search By Query Highlight error", e);
}

return null;
}

控制器:

@ApiOperation(value = "分页条件查询高亮")
@PostMapping("/api/v1/searchByQueryHighlight")
public ResponseResult searchByQueryHighlight(String index, String queryString, Integer pageNo, Integer pageSize) {
return ResponseResult.ok().data("goods", this.elasticSearchService.searchByQueryHighlight(index, queryString, pageNo, pageSize, Goods.class));
}

ES客户端索引相关操作

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2024年05月17日   48   0   0 查询mysql索引
  TEZNKK3IfmPf   2024年03月29日   58   0   0 mysql索引
TEZNKK3IfmPf