transportclient和restclient区别
使用springboot构建es项目主体方法有两种:transportclient
和restclient
。
-
方法一:transportclient
transportclient
是通过监听es端口的tcp链接进行数据传输,springboot项目可以通过引入spring-boot-starter-data-elasticsearch
来实现,是由spring官方所出。但是由于es版本更新较快,而官方内置的es版本更新速度慢,适配的都是较低版本,容易出现版本对应步上的问题。
-
方法二:restclient
restclient
是通过http来进行数据传输,相对于transportclient
,它的版本兼容性更好,可以通过整合elasticsearch-rest-high-level-client
来实现。且在官方说明中transportclient
会在es高版本中被弃用,故推荐使用restclient
;
elasticsearch项目构建
-
spring-boot-starter-data-elasticsearch
导入maven工程,es版本与导入的springboot版本相关
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
添加配置文件
spring.data.elasticsearch.client.reactive.endpoints=127.0.0.1:9200
#是否遵守SSL(Secure Sockets Layer 安全套接字协议)协议
spring.data.elasticsearch.client.reactive.use-ssl=false
#连接超时时间
spring.data.elasticsearch.client.reactive.connection-timeout=100000
spring.data.elasticsearch.client.reactive.socket-timeout=500000
#是否开启本地存储
spring.data.elasticsearch.repositories.enabled=true
创建一个实体类
@ApiModel(description = "Goods实体")
@Data
//type已被注释为过失,不传情况下,es会默认创建一个type为:_doc
@Document(indexName = "big_data_center_goods", type = "goods", shards = 2, replicas = 0)
public class Goods implements Serializable {
@ApiModelProperty(value = "主键ID")
//指定es中的id
@Id
private String id;
@ApiModelProperty(value = "店铺编码")
private String shopCode;
@ApiModelProperty(value = "商品名称")
private String goodsName;
@ApiModelProperty(value = "商品价格")
private BigDecimal price;
@ApiModelProperty(value = "商品描述")
private String desc;
@ApiModelProperty(value = "创建时间")
private String createTime;
}
创建repository
import cn.pdl.pelasticsearch.entity.Goods;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
//ElasticsearchRepository已继承ElasticsearchCrudRepository,其内置了很多方法实现,类似JPA,通过规范方法命名就能实现查询操作;
public interface GoodsRepository extends ElasticsearchRepository<Goods, String>{
Page<Goods> findAllByGoodsName(String shopName, Pageable pageable);
Page<Goods> findAllByShopCodeContains(String shopCode, Pageable pageable);
Page<Goods> findAllById(String id,Pageable pageable);
}
创建service层即其实现
public interface IGoodsService {
Optional<Goods> findById(String id);
Page<Goods> getGoods(String id, Pageable pageable);
Goods save(Goods blog);
Iterable<Goods> findAll();
Page<Goods> findByShopCode(String shopCode, Pageable pageable);
}
@Slf4j
@Service
public class GoodsServiceImpl implements IGoodsService {
@Autowired
@Qualifier("goodsRepository")
private GoodsRepository goodsRepository;
@Override
public Optional<Goods> findById(String id) {
Optional<Goods> optionalShop = null;
try {
optionalShop = goodsRepository.findById(id);
} catch (Exception e) {
log.error(">>>>>>>>>>>>>>>>>>>>>>", e);
}
return optionalShop;
}
@Override
public Page<Goods> getGoods(String id, Pageable pageable) {
return goodsRepository.findAllById(id,pageable);
}
@Override
public Goods save(Goods blog) {
Goods shop = null;
try {
shop = goodsRepository.save(blog);
} catch (Exception e) {
log.error(">>>>>>>>>>>>>>>>>>>>>>", e);
}
return shop;
}
@Override
public Iterable<Goods> findAll() {
Iterable<Goods> shops = null;
try {
shops = goodsRepository.findAll();
} catch (Exception e) {
log.error(">>>>>>>>>>>>>>>>>>>>>>", e);
}
return shops;
}
@Override
public Page<Goods> findByShopCode(String shopCode, Pageable pageable) {
Page<Goods> shopPage = null;
try {
shopPage = goodsRepository.findAllByShopCodeContains(shopCode, pageable);
} catch (Exception e) {
log.error(">>>>>>>>>>>>>>>>>>>>>>", e);
}
return shopPage;
}
}
创建controller层
@RestController
@RequestMapping("/es/appApi")
@Api(value = "es相关接口",tags = {"es相关"})
public class ESController {
@Autowired
IGoodsService goodsService;
@ApiOperation(value = "查询所有", notes="查询所有", httpMethod = "GET")
@GetMapping(value = "/findByAll")
public ResponseEntity<Iterable<Goods>> findByAll() {
Iterable<Goods> data = goodsService.findAll();
return new ResponseEntity<>(data, HttpStatus.OK);
}
@ApiOperation(value = "新增商品信息", notes="新增商品信息", httpMethod = "POST")
@PostMapping(value = "/createGoods")
public ResponseEntity<Goods> createGoods(@RequestBody Goods goods) {
String id = UUID.randomUUID().toString().replace("-", "");
String createTime = LocalDateTime.now().toString();
goods.setId(id);
goods.setCreateTime(createTime);
Goods data = goodsService.save(goods);
return new ResponseEntity<>(data, HttpStatus.OK);
}
}
-
elasticsearch-rest-high-level-client
导入maven工程,es版本可以自己根据需要来改变
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.3.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.3.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.3.1</version>
</dependency>
配置文件与上面一致
创建实体类
@Data
public class Goods {
private String goodsName;
private String goodsCode;
private String desc;
private String id;
//索引名称
private String indexName;
}
封装es方法,实现对数据的增删改查操作,对他入参可根据需要替换成扩展性更高的数据类型
import cn.pdl.pelasticsearch2.entity.Goods;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
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.client.ml.PostDataRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.awt.print.Pageable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
@Slf4j
public class ESUtil {
@Autowired
private RestHighLevelClient restHighLevelClient;
//创建索引
public String createIndex(String indexName) throws IOException {
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
createIndexRequest.index(indexName).settings(Settings.builder()
.put("index.number_of_shards",3)//设置分片数量,默认为5个
.put("index.number_of_replicas",2).build());//设置主分片数量
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
return createIndexRequest.index();
}
//判断索引是否存在
public boolean exists(String indexName) throws IOException {
GetIndexRequest getIndexRequest = new GetIndexRequest();
getIndexRequest.indices(indexName);
return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
}
//插入数据
public RestStatus insert(String indexName, Object object) throws IOException {
IndexRequest indexRequest = new IndexRequest();
// source方法里面需要填写对应数据的类型,默认数据类型为json
indexRequest.index(indexName).source(JSON.toJSONString(object), XContentType.JSON);
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
return response.status();
}
//查询索引下的所有数据
public List<Goods> search(Goods goods) throws IOException {
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder source = new SearchSourceBuilder();
source.from(0);
source.size(10);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
boolQueryBuilder.should(matchAllQueryBuilder);
searchRequest.indices(goods.getIndexName()).source(source);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<Goods> list=new ArrayList<>();
response.getHits().iterator().forEachRemaining(hit-> {
list.add(JSON.parseObject(hit.getSourceAsString(), Goods.class));
});
return list;
}
//根据条件查询
public List<Goods> searchByParams(Goods goods) throws IOException {
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder source = new SearchSourceBuilder();
source.from(0);
source.size(10);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
MatchQueryBuilder goodsName = QueryBuilders.matchQuery("goodsName", goods.getGoodsName());
MatchQueryBuilder desc = QueryBuilders.matchQuery("desc", goods.getDesc());
boolQueryBuilder.must(desc);
source.query(boolQueryBuilder);
searchRequest.indices(goods.getIndexName()).source(source);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<Goods> list=new ArrayList<>();
response.getHits().iterator().forEachRemaining(hit-> {
list.add(JSON.parseObject(hit.getSourceAsString(), Goods.class));
});
return list;
}
//根据条件删除数据
public Boolean deleteData(Goods goods) throws IOException{
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest();
SearchSourceBuilder source = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
MatchQueryBuilder goodsName = QueryBuilders.matchQuery("goodsName", goods.getGoodsName());
boolQueryBuilder.must(goodsName);
source.query(boolQueryBuilder);
deleteByQueryRequest.setQuery(boolQueryBuilder).indices(goods.getIndexName());
BulkByScrollResponse bulkByScrollResponse = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
return true;
}
//根据主键删除数据
public Boolean deleteById(String indexName,String id) throws IOException{
DeleteRequest deleteRequest = new DeleteRequest();
deleteRequest.index(indexName).id(id);
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
return true;
}
}
创建controller层
@Slf4j
@RestController
@RequestMapping("/es/2.0")
@Api(value = "es学习",tags = {"es学习"})
public class ESController {
@Autowired
private ESUtil esUtil;
@PostMapping("/createIndex")
@ApiOperation(value = "创建索引",notes = "创建索引")
public String createIndex(@RequestBody Goods goods){
try {
esUtil.createIndex(goods.getIndexName());
} catch (IOException e) {
return e.getMessage();
}
return "success";
}
@PostMapping("/insertData")
@ApiOperation(value = "插入数据",notes = "创建索引")
public String insertData(@RequestBody Goods goods){
try {
esUtil.insert("pdl",goods);
} catch (IOException e) {
return e.getMessage();
}
return "success";
}
@PostMapping("/findAll")
@ApiOperation(value = "查询所有",notes = "查询所有")
public List<Goods> findAll(@RequestBody Goods goods){
List<Goods> list = null;
try {
list = esUtil.search(goods);
} catch (IOException e) {
log.error(e.getMessage());
}
return list;
}
@PostMapping("/findAllByParams")
@ApiOperation(value = "根据条件查询所有",notes = "根据条件查询所有")
public List<Goods> findAllByParams(@RequestBody Goods goods){
List<Goods> list = null;
try {
list = esUtil.searchByParams(goods);
} catch (IOException e) {
log.error(e.getMessage());
}
return list;
}
@PostMapping("/delete")
@ApiOperation(value = "删除",notes = "删除")
public String delete(@RequestBody Goods goods){
List<Goods> list = null;
try {
esUtil.deleteData(goods);
} catch (IOException e) {
log.error(e.getMessage());
return e.getMessage();
}
return "success";
}
}
网友评论