SpringCloud 大型系列課程正在制作中,歡迎大家關(guān)注與提意見(jiàn)。
程序員每天的CV 與 板磚,也要知其所以然,本系列課程可以幫助初學(xué)者學(xué)習(xí) SpringBooot 項(xiàng)目開(kāi)發(fā) 與 SpringCloud 微服務(wù)系列項(xiàng)目開(kāi)發(fā)
elasticsearch是一款非常強(qiáng)大的開(kāi)源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容。
本項(xiàng)目數(shù)據(jù)庫(kù)使用的是 MySql ,查詢(xún)數(shù)據(jù)使用的是 ElasticSearch
本文章接 SpringBoot ElasticSearch 【SpringBoot系列16】
ES 中的數(shù)據(jù)查詢(xún)基本步驟:
- 第一步,創(chuàng)建
SearchRequest
對(duì)象,指定索引庫(kù)名 - 第二步,利用
request.source()
構(gòu)建DSL,DSL中可以包含查詢(xún)、分頁(yè)、排序、高亮等 - 第三步,利用client.search()發(fā)送請(qǐng)求,得到響應(yīng)
- 第四步 解析數(shù)據(jù)
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class ESDocumentTests {
@Resource
RestHighLevelClient restHighLevelClient;
@Test
void testMatchAll() throws IOException {
// 1.準(zhǔn)備Request
SearchRequest request = new SearchRequest("order");
// 2.準(zhǔn)備DSL
request.source()
.query(QueryBuilders.matchAllQuery());
// 3.發(fā)送請(qǐng)求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 4.解析響應(yīng)
handleResponse(response);
}
private void handleResponse(SearchResponse response) {
// 4.解析響應(yīng)
SearchHits searchHits = response.getHits();
// 4.1.獲取總條數(shù)
long total = searchHits.getTotalHits().value;
log.info("共搜索到" + total + "條數(shù)據(jù)");
// 4.2.文檔數(shù)組
SearchHit[] hits = searchHits.getHits();
// 4.3.遍歷
for (SearchHit hit : hits) {
// 獲取文檔source
String json = hit.getSourceAsString();
// 反序列化
Order order = JSON.parseObject(json, Order.class);
log.info("查詢(xún)到數(shù)據(jù) {}",order);
}
}
}
1 精確查詢(xún)
上述查詢(xún)中,QueryBuilders.matchAllQuery() 就是查詢(xún)條件,在這里沒(méi)有設(shè)置任何篩選條件,所以默認(rèn)返回前10條數(shù)據(jù)。
request.source()
.query(QueryBuilders.matchAllQuery());
如果要實(shí)現(xiàn)精確查詢(xún),需要構(gòu)建查詢(xún)條件:
@Test
public void testBool() throws IOException {
// 1.準(zhǔn)備Request
SearchRequest request = new SearchRequest("order");
// 2.準(zhǔn)備DSL
// 2.1.準(zhǔn)備BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 2.2.添加term
boolQuery.must(QueryBuilders.termQuery("goodsName", "手機(jī)"));
// 2.3.添加range
boolQuery.filter(QueryBuilders.rangeQuery("goodsPrice").lte(250));
//排序
request.source().query(boolQuery);
// 3.發(fā)送請(qǐng)求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 4.解析響應(yīng)
handleResponse(response);
}
核心就是這里的條件
- term:詞條精確匹配
- range:范圍查詢(xún)
// 2.2.添加term
boolQuery.must(QueryBuilders.termQuery("goodsName", "手機(jī)"));
// 2.3.添加range
boolQuery.filter(QueryBuilders.rangeQuery("goodsPrice").lte(250));
2 查詢(xún)結(jié)果排序與分頁(yè)
elasticsearch 在集群模式下,查詢(xún)TOP1000的數(shù)據(jù),例如我集群有5個(gè)節(jié)點(diǎn),就必須先查詢(xún)出每個(gè)節(jié)點(diǎn)的TOP1000,匯總結(jié)果后,重新排名,重新截取TOP1000。
當(dāng)查詢(xún)分頁(yè)深度較大時(shí),匯總數(shù)據(jù)過(guò)多,對(duì)內(nèi)存和CPU會(huì)產(chǎn)生非常大的壓力,因此elasticsearch會(huì)禁止from+ size 超過(guò)10000的請(qǐng)求。
@Test
public void testPageAndSort() throws IOException {
// 頁(yè)碼,每頁(yè)大小
int page = 1, size = 5;
// 1.準(zhǔn)備Request
SearchRequest request = new SearchRequest("order");
// 2.準(zhǔn)備DSL
// 2.1.query
request.source().query(QueryBuilders.matchAllQuery());
// 2.2.排序 sort
request.source().sort("price", SortOrder.ASC);
// 2.3.分頁(yè) from、size
request.source().from((page - 1) * size).size(5);
// 3.發(fā)送請(qǐng)求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 4.解析響應(yīng)
handleResponse(response);
}
核心代碼就是
- sort 排序
- from 分頁(yè)
// 2.2.排序 sort
request.source().sort("price", SortOrder.ASC);
// 2.3.分頁(yè) from、size
request.source().from((page - 1) * size).size(5);
3 本項(xiàng)目實(shí)現(xiàn)的 訂單分頁(yè)查詢(xún)
@Api(tags = "訂單模塊")
@RestController()
@RequestMapping("/orders")
@Slf4j
public class OrderController {
@Autowired
private OrderService orderService;
/**
* 查詢(xún)用戶(hù)所有的訂單
*/
@PostMapping("/list")
public PageResult listFromList(@RequestHeader Long userId,
@RequestBody RequestParams params) {
PageResult pageResult = orderService.listFromList(userId,params);
return pageResult;
}
}
PageResult 是分頁(yè)信息類(lèi)
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PageResult {
/**
* 當(dāng)前頁(yè)碼
*/
private int pageNum;
/**
* 每頁(yè)數(shù)量
*/
private int pageSize;
/**
* 記錄總數(shù)
*/
private long totalSize;
/**
* 頁(yè)碼總數(shù)
*/
private int totalPages;
/**
* 數(shù)據(jù)模型
*/
private List<?> content;
public PageResult(long total, List<Order> orderList) {
this.content = orderList;
this.totalSize = total;
}
}
RequestParams 是查詢(xún)條件 ,包括了分頁(yè)信息以及訂單的狀態(tài)
@Data
@AllArgsConstructor
public class RequestParams implements Serializable {
Integer page;
Integer pageSize;
Integer statues;
}
最后就是實(shí)現(xiàn)訂單的分頁(yè)查詢(xún)
@Resource
RestHighLevelClient restHighLevelClient;
/**
* 分頁(yè)查詢(xún)用戶(hù)的訂單
*
* @param userId
* @param params
* @return
*/
@Override
public PageResult listFromList(Long userId, RequestParams params) {
try {
// 1.準(zhǔn)備Request
SearchRequest request = new SearchRequest("order");
// 2.準(zhǔn)備DSL
// 1.構(gòu)建BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//查詢(xún)對(duì)應(yīng)用戶(hù)的
boolQuery.must(QueryBuilders.matchQuery("userId", userId));
//訂單狀態(tài)
if (params.getStatues() != null && params.getStatues()>=0) {
boolQuery.filter(QueryBuilders.termQuery("status", params.getStatues()));
}
// 分頁(yè)
int page = params.getPage();
int size = params.getPageSize();
request.source().from((page - 1) * size).size(size);
// 3.發(fā)送請(qǐng)求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 4.解析響應(yīng)
return handleResponse(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 結(jié)果解析
private PageResult handleResponse(SearchResponse response) {
// 4.解析響應(yīng)
SearchHits searchHits = response.getHits();
// 4.1.獲取總條數(shù)
long total = searchHits.getTotalHits().value;
// 4.2.文檔數(shù)組
SearchHit[] hits = searchHits.getHits();
// 4.3.遍歷
List<Order> hotels = new ArrayList<>();
for (SearchHit hit : hits) {
// 獲取文檔source
String json = hit.getSourceAsString();
// 反序列化
Order hotelDoc = JSON.parseObject(json, Order.class);
// 放入集合
hotels.add(hotelDoc);
}
// 4.4.封裝返回
return new PageResult(total, hotels);
}
4 訂單的其他操作
ES 中查詢(xún)訂單詳情
@Override
public Order getOrderDetailFromEs(Long orderId) {
// 創(chuàng)建獲取請(qǐng)求對(duì)象
GetRequest getRequest = new GetRequest("order", "83");
try {
GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
if(response.isExists()){
log.info("查詢(xún)到詳情 {}",response.getSourceAsString());
Order hotelDoc = JSON.parseObject(response.getSourceAsString(), Order.class);
return hotelDoc;
}else{
log.error("未消查詢(xún)到詳情");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
ES 中修改訂單狀態(tài)
/**
* 更新ES中訂單的狀態(tài)
* @param statues
*/
public void updateOrderStatues(Long orderId,Integer statues) {
// 設(shè)置商品更新信息
Order goods = new Order();
goods.setStatus(statues);
// 將對(duì)象轉(zhuǎn)為json
String data = JSON.toJSONString(goods);
// 創(chuàng)建索引請(qǐng)求對(duì)象
UpdateRequest updateRequest = new UpdateRequest("order", orderId.toString());
// 設(shè)置更新文檔內(nèi)容
updateRequest.doc(data, XContentType.JSON);
// 執(zhí)行更新文檔
UpdateResponse response = null;
try {
response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
throw new RuntimeException(e);
}
log.info("更新?tīng)顟B(tài):{}", response.status());
}
ES 中新增一條訂單數(shù)據(jù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-699863.html
/**
* 下單成功的時(shí)候 把數(shù)據(jù)保存到ES中
* @param order
*/
private void saveOrderToEs(Order order){
// 將對(duì)象轉(zhuǎn)為json
String data = JSON.toJSONString(order);
// 創(chuàng)建索引請(qǐng)求對(duì)象
// 參數(shù)一 索引庫(kù)名 參數(shù)二文檔名稱(chēng)
IndexRequest indexRequest = new IndexRequest("order").id(order.getId() + "");
// 準(zhǔn)備JSON文檔
indexRequest.source(data, XContentType.JSON);
// 執(zhí)行增加文檔
IndexResponse response = null;
try {
response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
log.info("創(chuàng)建狀態(tài):{}", response.status());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
項(xiàng)目源碼在這里 :https://gitee.com/android.long/spring-boot-study/tree/master/biglead-api-12-es
有興趣可以關(guān)注一下公眾號(hào):biglead文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-699863.html
- 創(chuàng)建SpringBoot基礎(chǔ)項(xiàng)目
- SpringBoot項(xiàng)目集成mybatis
- SpringBoot 集成 Druid 數(shù)據(jù)源【SpringBoot系列3】
- SpringBoot MyBatis 實(shí)現(xiàn)分頁(yè)查詢(xún)數(shù)據(jù)【SpringBoot系列4】
- SpringBoot MyBatis-Plus 集成 【SpringBoot系列5】
- SpringBoot mybatis-plus-generator 代碼生成器 【SpringBoot系列6】
- SpringBoot MyBatis-Plus 分頁(yè)查詢(xún) 【SpringBoot系列7】
- SpringBoot 集成Redis緩存 以及實(shí)現(xiàn)基本的數(shù)據(jù)緩存【SpringBoot系列8】
- SpringBoot 整合 Spring Security 實(shí)現(xiàn)安全認(rèn)證【SpringBoot系列9】
- SpringBoot Security認(rèn)證 Redis緩存用戶(hù)信息【SpringBoot系列10】
- SpringBoot 整合 RabbitMQ 消息隊(duì)列【SpringBoot系列11】
- SpringBoot 結(jié)合RabbitMQ與Redis實(shí)現(xiàn)商品的并發(fā)下單【SpringBoot系列12】
- SpringBoot 雪花算法生成商品訂單號(hào)【SpringBoot系列13】
- SpringBoot RabbitMQ 延時(shí)隊(duì)列取消訂單【SpringBoot系列14】
- SpringBoot RabbitMQ 商品秒殺【SpringBoot系列15】
- SpringBoot ElasticSearch 【SpringBoot系列16】
到了這里,關(guān)于SpringBoot ElasticSearch 實(shí)現(xiàn)訂單的分頁(yè)查詢(xún) 【SpringBoot系列17】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!