本篇内容主要讲解“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搜索的使用方法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/tingqianyunluo/blog/3286671