Dark Horse Programmer Microservices Dark Horse Travel Network

Table of contents

I. Introduction

2. Project display

3. Partial code display


I. Introduction

The tutorial in this article comes from the Dark Horse Travel Network project of Dark Horse Programmer's Microservice Tutorial .

Front-end technology stack

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

Backend technology stack

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

2. Project display

3. Partial code display

control layer

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 layer

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 layer

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

main startup class

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")
        ));
    }
​
}
​

4. File acquisition

Link: Baidu Netdisk Please enter the extraction code Extraction code: zhui

Guess you like

Origin blog.csdn.net/aasd23/article/details/129312638