开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情
1.创建Index
在这里我们不建议通过java api的方式创建索引,因为在实际的生当中,创建索引一般我们是要提工单通过运维去操作,创建索引的。我们只需要提供创建索引的json命令文件即可。
现在我们在kibana的界面,通过Dev Tools来创建一个索引。
假设实际这是我们的一个电商业务,我们在真个业务过程当中,商品的信息是需要不断的被检索的,所以在这我们建一个商品信息的索引。
主要包含的信息大概有商品唯一id、商品名称、商品标签价格,商品实际销售价格、库存、skuId等等,创建index的命令如下:
PUT /goods_item_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"category": {
"type": "keyword"
},
"basePrice": {
"type": "double"
},
"marketPrice": {
"type": "double"
},
"stockNum": {
"type": "integer"
},
"skuImgUrl": {
"type": "keyword",
"index": false
},
"skuId": {
"type": "keyword"
},
"skuName": {
"type": "text"
},
"createTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"updateTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
我们通过kibana创建这个索引。
右侧显示如下表示成功
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "goods_item_index"
}
2.新增
接下来我们通过kibana创建一条数据,我们通过PUT命令新增一条数据,PUT方式添加文档,如果不存在,则创建,如果存在,则更新,PUT方式添加文档,必须指定id。如果没有ID,提示以下错误。
先创建entity实体类用于跟ES进行交互 GoodsItems.java
@Data
public class GoodsItem {
private Long id;
private String category;
private BigDecimal basePrice;
private BigDecimal marketPrice;
private Integer stockNum;
private String skuImgUrl;
private String skuId;
private String skuName;
@DateTimeFormat(pattern = "yyyy-mm-dd HH:mm:ss")
private Date createTime;
@DateTimeFormat(pattern = "yyyy-mm-dd HH:mm:ss")
private Date updateTime;
}
创建响应类跟请求类
com.daiyu.elastic.domain.request.GoodsItemReq.java
@Data
public class GoodsItemReq {
private Long id;
private String category;
private BigDecimal basePrice;
private BigDecimal marketPrice;
private Integer stockNum;
private String skuImgUrl;
private String skuId;
private String skuName;
@DateTimeFormat(pattern = "yyyy-mm-dd HH:mm:ss")
private Date createTime;
@DateTimeFormat(pattern = "yyyy-mm-dd HH:mm:ss")
private Date updateTime;
}
com.daiyu.elastic.domain.reponse.GoodsItemRep.java
@Data
public class GoodsItemRep {
private Long id;
private String category;
private BigDecimal basePrice;
private BigDecimal marketPrice;
private Integer stockNum;
private String skuImgUrl;
private String skuId;
private String skuName;
@DateTimeFormat(pattern = "yyyy-mm-dd HH:mm:ss")
private Date createTime;
@DateTimeFormat(pattern = "yyyy-mm-dd HH:mm:ss")
private Date updateTime;
}
service接口com.daiyu.elastic.service.GoodsService
/**
* 单条插入
*
* @param goodsItemReq 请求体
* @return 成功与否
*/
Boolean insertGoods(GoodsItemReq goodsItemReq);
接口实现类com.daiyu.elastic.service.GoodsServiceImpl,新增方法
@Override
public Boolean insertGoods(GoodsItemReq goodsItemReq) {
GoodsItem goodsItem = new GoodsItem();
BeanUtils.copyProperties(goodsItemReq, goodsItem);
Result insert = client.insert(goodsItemReq.getSkuId(), index, goodsItem);
if (insert == Result.Updated) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
controller,com.daiyu.elastic.controller.GoodsController.java
@PostMapping("/insertGoods")
@ResponseBody
private BaseResponse<Boolean> insertGoods(@RequestBody GoodsItemReq goodsItemReq) {
BaseResponse<Boolean> baseResponse = new BaseResponse<>();
baseResponse.setData(goodsService.insertGoods(goodsItemReq));
baseResponse.setCode(200);
baseResponse.setMsg("插入成功");
return baseResponse;
}
接下来我们通过,postman等工具对接口进行起请求
curl --location --request POST 'http://localhost:8089/goods/insertGoods' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": 2,
"category": "phone",
"basePrice": 1000.00,
"marketPrice": 900.00,
"stockNum": 100,
"skuImgUrl": "http://www.xiaom.com?dsdsds",
"skuId": "p1000001",
"skuName": "小米手机",
"createTime": "2022-01-01 00:00:00",
"updateTime": "2022-01-01 00:00:00"
}'
成功结果如下
现在GoodsService新增批量插入方法
/**
* 批量插入
*
* @param goodsItemReqs 请求体
* @return 成功与否
*/
Boolean bulkInsertGoods(List<GoodsItemReq> goodsItemReqs);
实现方法
@Override
public Boolean bulkInsertGoods(List<GoodsItemReq> goodsItemReqs) {
List<GoodsItem> goodsItems = new ArrayList<>();
for (GoodsItemReq goodsItemReq : goodsItemReqs) {
GoodsItem goodsItem = new GoodsItem();
BeanUtils.copyProperties(goodsItemReq, goodsItem);
goodsItems.add(goodsItem);
}
BulkRequest.Builder br = new BulkRequest.Builder();
for (GoodsItem goodsItem : goodsItems) {
br.operations(op -> op
.index(idx -> idx
.index(index)
.id(goodsItem.getId().toString())
.document(goodsItem)
)
);
}
return client.bulkInsert(br);
}
ElasticsearchUtil工具类新增批量插入通用方法
/**
* 批量插入
*
* @param br build
* @throws IOException
*/
public Boolean bulkInsert(BulkRequest.Builder br) {
BulkResponse bulkResponse = null;
try {
bulkResponse = client.bulk(br.build());
} catch (IOException e) {
log.info(e.getMessage(), e);
}
if (bulkResponse.errors()) {
log.error("插入存在错误");
for (BulkResponseItem item : bulkResponse.items()) {
if (item.error() != null) {
log.error(item.error().reason());
}
}
return false;
} else {
log.info("全部插入完成");
return true;
}
}
然后通过postman等工具对接口进行起请求
op 是一个构建器,
BulkOperation它是一个构造器。此类型可以进行index、create和update、delete操作的构建。
curl --location --request POST 'http://localhost:8089/goods/bulkInsertGoods' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"id": 3,
"category": "phone",
"basePrice": 1000.00,
"marketPrice": 900.00,
"stockNum": 100,
"skuImgUrl": "http://www.xiaom.com?dsdsds",
"skuId": "p1000001",
"skuName": "vivo手机",
"createTime": "2022-01-01 00:00:00",
"updateTime": "2022-01-01 00:00:00"
},
{
"id": 4,
"category": "phone",
"basePrice": 1000.00,
"marketPrice": 900.00,
"stockNum": 100,
"skuImgUrl": "http://www.xiaom.com?dsdsds",
"skuId": "p1000001",
"skuName": "oppo手机",
"createTime": "2022-01-01 00:00:00",
"updateTime": "2022-01-01 00:00:00"
}
]'
根据ID进行查询
在service里边新增方法
/**
* 根据ID进行查询
*
* @param id id
* @return 响应结果
*/
List<GoodsItemRep> queryById(Long id);
方法的具体实现
@Override
public List<GoodsItemRep> queryById(Long id) {
Query query = MatchQuery.of(m -> m
.query(id.toString())
)._toQuery();
List<GoodsItem> result = client.search(index, GoodsItem.class, query);
List<GoodsItemRep> goodsItemReps = new ArrayList<>();
for (GoodsItem goodsItem : result) {
GoodsItemRep goodsItemRep = new GoodsItemRep();
BeanUtils.copyProperties(goodsItem, goodsItemRep);
goodsItemReps.add(goodsItemRep);
}
return goodsItemReps;
}
通过postman查询结构
curl --location --request GET 'http://localhost:8089/goods/queryGoodsById?id=3'
根据id进行修改,这里我们只需要调用client的insert方法即可,只要我们的_id跟es里边的数据存在的Id对应即可。
@Override
public Boolean updateGoods(GoodsItemReq goodsItemReq) {
GoodsItem goodsItem = new GoodsItem();
BeanUtils.copyProperties(goodsItemReq, goodsItem);
Result insert = client.insert(goodsItemReq.getId().toString(), index, goodsItem);
if (insert == Result.Updated) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
postman进行接口请求
curl --location --request POST 'http://localhost:8089/goods/updateGoods' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": 2,
"category": "phone",
"basePrice": 1000.00,
"marketPrice": 900.00,
"stockNum": 100,
"skuImgUrl": "http://www.xiaom.com?dsdsds",
"skuId": "p1000001",
"skuName": "小米手机2222",
"createTime": "2022-01-01 00:00:00",
"updateTime": "2022-01-01 00:00:00"
}'
虽然说,es不建议修改或者删除数据,但是我们还是要学习一下删除的API操作
在service新增删除方法
/**
* @param id 根据ID进行删除
* @return 成功与否
*/
Boolean deleteGoodsById(Long id);
实现类 的方法
@Override
public Boolean deleteGoodsById(Long id) {
Result result = client.deleteById(index, id.toString());
if (result == Result.Deleted) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
在ElasticsearchUtil工具类新增根据id删除数据的方法
/**
* 根据_id删除索引数据
*
* @param index 索引名称
* @param id _id
* @return
*/
public Result deleteById(String index, String id) {
DeleteResponse deleteResponse = null;
try {
deleteResponse = client.delete(d -> d.index(index).id(id));
} catch (IOException e) {
log.info(e.getMessage(), e);
}
return deleteResponse.result();
}
在postman里边调用,删除_id为1的数据
curl --location --request POST 'http://localhost:8089/goods/deleteGoodsById?id=1'
GET goods_item_index/_search
{
"query": {
"term": {
"_id": 1
}
}
}
可以看到_id为1的数据成功删除