黑马程序员微服务黑马旅游网

目录

一、前言

二、项目展示

三、部分代码展示


一、前言

本文章教程来自于黑马程序员的微服务教程 的黑马旅游网项目。

前端技术栈

html5、css3、JavaScript、vue、element-ui、axios

后端技术栈

springboot、Elasticsearch、RabbitMQ、Docker、mybatis-plus等。

二、项目展示

三、部分代码展示

控制层

package cn.itcast.hotel.web;
​
​
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import cn.itcast.hotel.service.IHotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
​
import java.io.IOException;
import java.util.List;
import java.util.Map;
​
@RestController
@RequestMapping("/hotel")
public class HotelController {
​
    @Autowired
    private IHotelService hotelService;
​
    @PostMapping("/list")
    public PageResult search(@RequestBody RequestParams params) throws IOException {
​
        return hotelService.search(params);
    }
​
    @PostMapping("/filters")
    public Map<String, List<String>> filters(@RequestBody RequestParams params) throws IOException {
        return hotelService.filters(params);
    }
​
    @GetMapping("suggestion")
    public List<String> getSuggestions(@RequestParam("key") String prefix){
        return hotelService.getSuggestions(prefix);
    }
​
}

service层

package cn.itcast.hotel.service.impl;
​
import cn.itcast.hotel.mapper.HotelMapper;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
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.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
​
import javax.swing.border.SoftBevelBorder;
import java.io.IOException;
import java.util.*;
​
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
​
    @Autowired
    private RestHighLevelClient client;
​
    @Override
    public PageResult search(RequestParams params) {
        try {
​
//        准备request
            SearchRequest request = new SearchRequest("hotel");
            buildBasicQuery(params, request);
​
//        分页
            int page = params.getPage();
            int size = params.getSize();
            request.source().from((page - 1) * size).size(size);
//            排序
            String location  = params.getLocation();
​
            if (location != null && !location.equals("")){
                request.source().sort(SortBuilders
                        .geoDistanceSort("location", new GeoPoint(location))
                        .order(SortOrder.ASC)
                        .unit(DistanceUnit.KILOMETERS)
                );
            }
​
//        发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
​
            return handleResponse(response);
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
​
    @Override
    public Map<String, List<String>> filters(RequestParams params) {
​
        try {
//        准备request
            SearchRequest request = new SearchRequest("hotel");
//        query
            buildBasicQuery(params, request);
//        准备dsl
//        设置size
            request.source().size(0);
//        聚合
            buildAggregation(request);
​
//        发送请求
            Map<String, List<String>> result = new HashMap<>();
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//        解析响应
//        根据名称获取品牌的结果
            Aggregations aggregations = response.getAggregations();
//        获取聚合结果
            List<String> brandList = getAggByName(aggregations, "brandAgg");
            result.put("brand", brandList);
​
            List<String> cityList = getAggByName(aggregations, "cityAgg");
            result.put("city", cityList);
​
            List<String> starList = getAggByName(aggregations, "starAgg");
            result.put("starName", starList);
​
            return result;
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
​
    @Override
    public List<String> getSuggestions(String prefix) {
//        System.out.println("prefix = " + prefix);
        try {
//        准备request
            SearchRequest request = new SearchRequest("hotel");
​
            request.source().suggest(new SuggestBuilder().addSuggestion(
                    "suggestions",
                    SuggestBuilders.completionSuggestion("suggestion")
                            .prefix(prefix)
                            .skipDuplicates(true)
                            .size(10)
            ));
​
//        发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//        解析结果
            Suggest suggest = response.getSuggest();
//        根据补全的名称,获取补全的结果
            CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
//        获取 options
            List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
//        遍历
            List<String> list = new ArrayList<>();
            for (CompletionSuggestion.Entry.Option option : options) {
                String s = option.getText().toString();
                list.add(s);
            }
            return list;
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
​
    @Override
    public void deleteById(Long id) {
        try {
            // 1.准备Request
            DeleteRequest request = new DeleteRequest("hotel", id.toString());
            // 2.发送请求
            client.delete(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
​
    @Override
    public void insertById(Long id) {
        try {
            // 0.根据id查询酒店数据
            Hotel hotel = getById(id);
            // 转换为文档类型
            HotelDoc hotelDoc = new HotelDoc(hotel);
​
            // 1.准备Request对象
            IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
            // 2.准备Json文档
            request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
            // 3.发送请求
            client.index(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
​
    private List<String> getAggByName(Aggregations aggregations,String aggName) {
        Terms brandTerms = aggregations.get(aggName);
//        获取 buckets
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
//        遍历
        List<String> brandList = new ArrayList<>();
        for (Terms.Bucket bucket : buckets) {
//            获取key
            String key = bucket.getKeyAsString();
            brandList.add(key);
            System.out.println("key = " + key);
        }
        return brandList;
    }
​
    private void buildAggregation(SearchRequest request) {
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(100)
        );
        request.source().aggregation(AggregationBuilders
                .terms("cityAgg")
                .field("city")
                .size(100)
        );
        request.source().aggregation(AggregationBuilders
                .terms("starAgg")
                .field("starName")
                .size(100)
        );
    }
​
    private void buildBasicQuery(RequestParams params, SearchRequest request) {
        //        准备dsl,获取数据
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
​
        String sortBy = params.getSortBy();
        if (!Objects.equals(sortBy, "default")) {
            request.source().query(QueryBuilders.matchAllQuery());
            request.source().sort(sortBy, SortOrder.ASC);
        }
​
//            关键字搜索
        String key = params.getKey();
        if (Objects.equals(key, "") || key == null) {
            boolQuery.must(QueryBuilders.matchAllQuery());
        } else {
            boolQuery.must(QueryBuilders.matchQuery("all", key));
        }
//             城市条件
        if (params.getCity() != null && !params.getCity().equals("")){
            boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
        }
//             品牌条件
        if (params.getBrand() != null && !params.getBrand().equals("")){
            boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
        }
//             星级条件
        if (params.getStarName() != null && !params.getStarName().equals("")){
            String temp = "";
            if (Objects.equals(params.getStarName(), "四星")){
                temp = params.getStarName() + "级";
                boolQuery.filter(QueryBuilders.termQuery("starName", temp));
            }else if (Objects.equals(params.getStarName(), "五星")){
                temp = params.getStarName() + "级";
                boolQuery.filter(QueryBuilders.termQuery("starName", temp));
            }else {
                boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));
            }
        }
//            价格条件
        if (params.getMinPrice() != null && params.getMaxPrice() != null){
            boolQuery.filter(QueryBuilders
                    .rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
        }
​
        FunctionScoreQueryBuilder functionScoreQuery =
                QueryBuilders.functionScoreQuery(
//                        原始查询
                        boolQuery,
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
//                                其中一个function score 元素
                                new FunctionScoreQueryBuilder.FilterFunctionBuilder(
//                                        过滤条件
                                        QueryBuilders.termQuery("isAD", true),
//                                        算分函数,默认为乘法
                                        ScoreFunctionBuilders.weightFactorFunction(10)
                                )
                        }
                );
​
        request.source().query(functionScoreQuery);
    }
​
    //    抽取方法
    private PageResult handleResponse(SearchResponse response) {
        //        响应解析
        SearchHits searchHits = response.getHits();
//        获取条数
        long total = searchHits.getTotalHits().value;
​
        System.out.println(total);
//        获取htis(黑丝)
        SearchHit[] hits = searchHits.getHits();
​
        List<HotelDoc> hotels = new ArrayList<>();
​
        for (SearchHit hit : hits) {
//            获取文档source
            String json = hit.getSourceAsString();
//            反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
​
            Object[] sortValues = hit.getSortValues();
​
            if (sortValues.length > 0){
                Object sortValue = sortValues[0];
                hotelDoc.setDistance(sortValue);
            }
​
            hotels.add(hotelDoc);
        }
​
        return new PageResult(total, hotels);
    }
​
}
​

mapper层

//@Mapper
public interface HotelMapper extends BaseMapper<Hotel> {
}

主启动类

package cn.itcast.hotel;
​
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
​
@MapperScan("cn.itcast.hotel.mapper")
@SpringBootApplication
public class HotelDemoApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(HotelDemoApplication.class, args);
    }
​
    @Bean
    public RestHighLevelClient client(){
        return new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.71.133:9200")
        ));
    }
​
}
​

四、文件获取

链接:百度网盘 请输入提取码 提取码:zhui

猜你喜欢

转载自blog.csdn.net/aasd23/article/details/129312638