您好,登錄后才能下訂單哦!
本篇內容主要講解“Elastic搜索的使用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Elastic搜索的使用方法”吧!
規格選項:點擊規格選項,需要拼湊條件
點擊不限,需要將對應條件移除
"specList": { "機身顏色": "金色", "內存": "3GB" },
1、修改 ~/pages/_cid.vue組件,給每一個選項綁定事件(含"不限")
參數:規格名稱、選項的值、event(鼠標事件對象,用于回顯)
2、編寫specSearch函數,用于操作data查詢條件,需要在searchMap添加specList條件
如果選項值不為Null,添加條件
如果選項值為Null,刪除條件
specSearch(specName, optionName, e) { //參數1:specName 規格名稱 //參數2:optionName 規格選項的值 //1) 處理條件:選擇值,如果存在添加條件,如果不存在刪除條件 if (optionName){ //存在 this.searchMap.specList[specName] = optionName; } else { //不存在 delete this.searchMap.specList[specName]; } //重新查詢 this.searchList(); //方式1:jquery代碼 處理回顯 //獲得事件源 a 標簽,再獲得父標簽<dd>,再添加用時 $(e.target).parent().addClass("cur"); //獲得 a 標簽父元素的所有,將樣式移除 $(e.target).parent().siblings().removeClass("cur"); },
需要使用修改后的品牌進行查詢
brandSearch(bid) { //切換品牌 this.searchMap.brandId = bid; //查詢 this.searchList(); },
1、修改頭部搜索的組件,添加keyword變量與文本框進行數據綁,給搜索按鈕綁定事件
data() { return { keyword: "" }; }
2、操作vuex,將keyword保存到vuex中
注意:vuex中必須有對應的變量
sotre/index.js
//state區域,相當于定義變量 export const state = () => ({ user: null, keyword: null }) //mutations區域,用于修改數據 export const mutations = { setData(state, obj) { state[obj.key] = obj.value } }
HeaderSearch.vue
3、修改列表頁面,添加 watch 對 vuex 中keyword進行監控,如果數據發生改變進行查詢
注意:在 watch 只能使用普通fuction,不能使用箭頭函數
watch: { "$store.state.keyword": function(newValue, oldValue) { //添加 keyword 查詢條件 this.searchMap.keyword = newValue; //查詢 this.searchList(); } }
價格的需求:
第一次點擊時,按照價格升序進行排序
第一次之后,按照當前排序取反進行操作。
1、給排序的按鈕綁定事件,傳遞唯一標識(xl、sj等)、點擊后加上高亮
<dl> <dt>排序:</dt> <dd :class="{'cur': searchMap.sortBy == 'xl'}"> <a href @click.prevent="sortSearch('xl')">銷量</a> </dd> <dd :class="{'cur': searchMap.sortBy == 'jg'}"> <a href @click.prevent="sortSearch('jg')"> 價格 <!-- 升序:價格由低到高 --> <span v-if="searchMap.sortBy == 'jg' && searchMap.sortWay=='asc'">↑</span> <!-- 降序:價格由高到低 --> <span v-if="searchMap.sortBy == 'jg' && searchMap.sortWay=='desc'">↓</span> </a> </dd> <dd :class="{'cur': searchMap.sortBy == 'pl'}"> <a href @click.prevent="sortSearch('pl')">評論數</a> </dd> <dd :class="{'cur': searchMap.sortBy == 'sj'}"> <a href @click.prevent="sortSearch('sj')">上架時間</a> </dd>價格: <input type="number" v-model="searchMap.minPrice" placeholder="¥" /> - <input type="number" v-model="searchMap.maxPrice" placeholder="¥" /> <input type="submit" value="搜索" @click.prevent="searchList()" /> </dl>
2、編寫排序函數 sortSearch,根據點擊次數,修改升降序方法
sortSearch(sortBy) { //第一次點擊、之后切換排序方式 if (this.searchMap.sortBy == sortBy) { //點擊第二次切換排序方式 this.searchMap.sortWay = this.searchMap.sortWay == "asc" ? "desc" : "asc"; } else { //第一次默認升序 this.searchMap.sortBy = sortBy; this.searchMap.sortWay = "asc"; } this.searchList(); }
<input type="text" v-model="searchMap.minPrice" name="" id=""> - <input type="text" v-model="searchMap.maxPrice" name="" id=""> <input type="button" @click.prevent="searchList" value="搜索">
1、拷貝分頁組件
<template> <div class="page mt20"> <a href v-if="page > 1" @click.prevent="pageClick(1)">首頁</a> <a href v-if="page > 1" @click.prevent="pageClick(page-1)">上一頁</a> <a href v-for="n in pageRange" :key="n" @click.prevent="pageClick(n)" :class="{'cur': page == n}" >{{n}}</a> <a href v-if="page < totalPage" @click.prevent="pageClick(page+1)">下一頁</a> <a href v-if="page < totalPage" @click.prevent="pageClick(totalPage)">尾頁</a> <span> <em> 共{{totalPage}}頁 到第 <input type="text" class="page_num" v-model="goNum" /> 頁 </em> <a href class="skipsearch" @click.prevent="pageClick(goNum)">確定</a> </span> </div> </template> <script> export default { data() { return { page: 1, //當前第幾頁 totalPage: 0, //總分頁數 goNum: 1 //跳轉頁面 }; }, methods: { pageClick: function(n) { //修改當前頁 this.page = parseInt(n); //通知調用,修改數據 this.$emit("page_changed", n); } }, computed: { //計算屬性 pageRange: function() { //計算總分頁數 -- 100/20 = 5 102/20 = 6 if (this.total % this.page_size == 0) { //整除 this.totalPage = this.total / this.page_size; } else { this.totalPage = parseInt(this.total / this.page_size) + 1; } //分頁范圍 let star = Math.max(this.page - 5, 1); //范圍開始:得到一個 >=1 的數字 let end = Math.min(this.page + 4, this.totalPage); //范圍結束:得到一個 <=end 的數字 let arr = []; for (let i = star; i <= end; i++) { arr.push(i); } return arr; } }, props: ["total", "page_size"] //總條數 , 每頁顯示個數 }; </script> <style> </style>
2、導入分頁組件
3、使用分頁組件,總條數、每頁顯示的個數、回調函數
<pagination :total="searchResult.count" :page_size="searchMap.pageSize" @page_changed="pageChanged"> </pagination>
total屬性:總條數 (查詢結果)
page_size:每頁顯示個數(查詢條件)
@page_changed :每一頁需要執行函數
4、編寫回調函數,處理頁面切換
pageChanged: function(pageNum) { //根據第幾頁查詢數據 this.searchMap.pageNum = pageNum; //查詢 this.searchList(); }
Controller
package com.czxy.controller; import com.czxy.service.SkuSearchService; import com.czxy.vo.BaseResult; import com.czxy.vo.SearchVo; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.Map; /** * @author 庭前云落 * @Date 2020/4/15 21:39 * @description */ @RestController @RequestMapping("/sku") public class SkuSearchController { @Resource private SkuSearchService skuSearchService; @PostMapping("/search") public BaseResult findSkus(@RequestBody SearchVo searchVo) { if (searchVo.getCatId() == null) { return BaseResult.error("分類不能為空"); } Map search = skuSearchService.search(searchVo); System.out.println(search); return BaseResult.ok("查詢成功", search); } }
Service
package com.czxy.service.impl; import com.czxy.repository.SkuRepository; import com.czxy.service.SkuSearchService; import com.czxy.vo.ReturnSku; import com.czxy.vo.SearchSku; import com.czxy.vo.SearchVo; import org.apache.commons.lang.StringUtils; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author 庭前云落 * @Date 2020/4/15 21:40 * @description */ @Service public class SkuSearchServiceImpl implements SkuSearchService { @Resource private SkuRepository skuRepository; public Map search(SearchVo searchVo){ BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //分類查詢 boolQueryBuilder.must(QueryBuilders.termQuery("catId",searchVo.getCatId())); //關鍵字查詢 if(StringUtils.isNotBlank(searchVo.getKeyword())){ boolQueryBuilder.must(QueryBuilders.matchQuery("skuName",searchVo.getKeyword())); } //品牌查詢 if(searchVo.getBrandId()!=null){ boolQueryBuilder.must(QueryBuilders.termQuery("brandId",searchVo.getBrandId())); } //規格查詢 Map<String, String> specList = searchVo.getSpecList(); if(specList!=null){ for (Map.Entry<String, String> entry : specList.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); boolQueryBuilder.must(QueryBuilders.termQuery("spces."+key+".keyword",value)); } } if(searchVo.getMaxPrice()!=null&&searchVo.getMaxPrice()!=null){ boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(searchVo.getMinPrice()).lt(searchVo.getMaxPrice())); } NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(boolQueryBuilder); if (searchVo.getSortBy()!=null){ if(searchVo.getSortBy().equals("xl")&&searchVo.getSortWay().equals("asc")){ //銷量升序 queryBuilder.withSort(SortBuilders.fieldSort("sellerCount").order(SortOrder.ASC)); }else if(searchVo.getSortBy().equals("xl")&&searchVo.getSortWay().equals("desc")) { // 銷量降序 queryBuilder.withSort(SortBuilders.fieldSort("sellerCount").order(SortOrder.DESC)); }else if(searchVo.getSortBy().equals("jg")&&searchVo.getSortWay().equals("asc")){ // 價格升序 queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC)); }else if(searchVo.getSortBy().equals("jg")&&searchVo.getSortWay().equals("desc")) { // 價格降序 queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC)); }else if(searchVo.getSortBy().equals("pl")&&searchVo.getSortWay().equals("asc")){ // 評論升序 queryBuilder.withSort(SortBuilders.fieldSort("commentCount").order(SortOrder.ASC)); }else if(searchVo.getSortBy().equals("pl")&&searchVo.getSortWay().equals("desc")) { // 評論降序 queryBuilder.withSort(SortBuilders.fieldSort("commentCount").order(SortOrder.DESC)); }else if(searchVo.getSortBy().equals("sj")&&searchVo.getSortWay().equals("asc")){ // 上架時間 queryBuilder.withSort(SortBuilders.fieldSort("onSaleTime").order(SortOrder.ASC)); }else if(searchVo.getSortBy().equals("sj")&&searchVo.getSortWay().equals("desc")) { // 上架時間 queryBuilder.withSort(SortBuilders.fieldSort("onSaleTime").order(SortOrder.DESC)); } } // 2.2 分頁 queryBuilder.withPageable(PageRequest.of(searchVo.getPageNum() - 1 ,searchVo.getPageSize())); //3 查詢,獲取結果 // 3.1 查詢 Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build()); // 2.2 總條數 long total = pageInfo.getTotalElements(); // 3.3 獲取返回結果 ,組裝返回數據(SearchSku-->Return) List<SearchSku> list = pageInfo.getContent(); List<ReturnSku> returnList = new ArrayList<>(); for(SearchSku sku:list){ //創建 ReturnSku對象 ReturnSku rs = new ReturnSku(); //依次填充數據 rs.setId(sku.getId().intValue()); rs.setGoodsName(sku.getSkuName()); rs.setMidlogo(sku.getLogo()); rs.setCommentCount(sku.getCommentCount()); rs.setPrice(sku.getPrice()); returnList.add(rs); } // 3.4 封裝 Map result = new HashMap(); result.put("count" , total); result.put("list" ,returnList); return result; } }
到此,相信大家對“Elastic搜索的使用方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。