diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8f7e7ba
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea
+/target
+/src/test
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
index 8b2b496..eb1de1b 100644
--- a/.idea/dataSources.xml
+++ b/.idea/dataSources.xml
@@ -15,5 +15,17 @@
$ProjectFileDir$
+
+ postgresql
+ true
+ org.postgresql.Driver
+ jdbc:postgresql://192.168.249.131:5432/postgres
+
+
+
+
+
+ $ProjectFileDir$
+
\ No newline at end of file
diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml
new file mode 100644
index 0000000..02b915b
--- /dev/null
+++ b/.idea/git_toolbox_prj.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index abb532a..cf3be90 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -1,6 +1,11 @@
+
+
+
+
+
@@ -16,5 +21,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/cn/itcast/hotel/HotelDemoApplication.java b/src/main/java/cn/itcast/hotel/HotelDemoApplication.java
index 518760e..6070f5b 100644
--- a/src/main/java/cn/itcast/hotel/HotelDemoApplication.java
+++ b/src/main/java/cn/itcast/hotel/HotelDemoApplication.java
@@ -1,13 +1,14 @@
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 {
@@ -16,4 +17,11 @@ public class HotelDemoApplication {
SpringApplication.run(HotelDemoApplication.class, args);
}
+ @Bean
+ public RestHighLevelClient restHighLevelClient() {
+ return new RestHighLevelClient(RestClient.builder(
+ HttpHost.create("http://192.168.249.131:9200")
+ ));
+ }
+
}
diff --git a/src/main/java/cn/itcast/hotel/controller/HotelController.java b/src/main/java/cn/itcast/hotel/controller/HotelController.java
new file mode 100644
index 0000000..3b7f553
--- /dev/null
+++ b/src/main/java/cn/itcast/hotel/controller/HotelController.java
@@ -0,0 +1,24 @@
+package cn.itcast.hotel.controller;
+
+import cn.itcast.hotel.pojo.PageResult;
+import cn.itcast.hotel.pojo.RequestParams;
+import cn.itcast.hotel.service.IHotelService;
+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;
+
+@RestController
+@RequestMapping("/hotel")
+public class HotelController {
+
+ @Resource
+ private IHotelService hotelService;
+
+ @PostMapping("/list")
+ public PageResult search(@RequestBody RequestParams requestParams) {
+ return hotelService.search(requestParams);
+ }
+}
diff --git a/src/main/java/cn/itcast/hotel/pojo/HotelDoc.java b/src/main/java/cn/itcast/hotel/pojo/HotelDoc.java
index 4d393b9..1d84b38 100644
--- a/src/main/java/cn/itcast/hotel/pojo/HotelDoc.java
+++ b/src/main/java/cn/itcast/hotel/pojo/HotelDoc.java
@@ -17,6 +17,8 @@ public class HotelDoc {
private String business;
private String location;
private String pic;
+ private Object distance;
+ private Boolean isAd;
public HotelDoc(Hotel hotel) {
this.id = hotel.getId();
diff --git a/src/main/java/cn/itcast/hotel/pojo/PageResult.java b/src/main/java/cn/itcast/hotel/pojo/PageResult.java
new file mode 100644
index 0000000..9e3637a
--- /dev/null
+++ b/src/main/java/cn/itcast/hotel/pojo/PageResult.java
@@ -0,0 +1,15 @@
+package cn.itcast.hotel.pojo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class PageResult {
+ private Long total;
+ private List hotelList;
+}
diff --git a/src/main/java/cn/itcast/hotel/pojo/RequestParams.java b/src/main/java/cn/itcast/hotel/pojo/RequestParams.java
new file mode 100644
index 0000000..0c1932d
--- /dev/null
+++ b/src/main/java/cn/itcast/hotel/pojo/RequestParams.java
@@ -0,0 +1,17 @@
+package cn.itcast.hotel.pojo;
+
+import lombok.Data;
+
+@Data
+public class RequestParams {
+ private String key;
+ private Integer page;
+ private Integer size;
+ private String sortBy;
+ private String city;
+ private String brand;
+ private String starName;
+ private Integer minPrice;
+ private Integer maxPrice;
+ private String location;
+}
diff --git a/src/main/java/cn/itcast/hotel/service/IHotelService.java b/src/main/java/cn/itcast/hotel/service/IHotelService.java
index d4ab356..297efe5 100644
--- a/src/main/java/cn/itcast/hotel/service/IHotelService.java
+++ b/src/main/java/cn/itcast/hotel/service/IHotelService.java
@@ -1,7 +1,10 @@
package cn.itcast.hotel.service;
import cn.itcast.hotel.pojo.Hotel;
+import cn.itcast.hotel.pojo.PageResult;
+import cn.itcast.hotel.pojo.RequestParams;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IHotelService extends IService {
+ PageResult search(RequestParams requestParams);
}
diff --git a/src/main/java/cn/itcast/hotel/service/impl/HotelService.java b/src/main/java/cn/itcast/hotel/service/impl/HotelService.java
index 5a312ac..b035d8a 100644
--- a/src/main/java/cn/itcast/hotel/service/impl/HotelService.java
+++ b/src/main/java/cn/itcast/hotel/service/impl/HotelService.java
@@ -2,10 +2,96 @@ 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.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.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.sort.SortBuilders;
+import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
@Service
public class HotelService extends ServiceImpl implements IHotelService {
+
+ @Resource
+ private RestHighLevelClient client;
+
+ @Override
+ public PageResult search(RequestParams params) {
+ SearchRequest request = new SearchRequest("hotel");
+ BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
+
+ paramCheck(params, boolQuery);
+
+ Integer page = params.getPage();
+ Integer size = params.getSize();
+ request.source().from((page - 1) * size).size(size);
+ if (StringUtils.isEmpty(params.getLocation())) {
+ request.source().sort(SortBuilders
+ .geoDistanceSort("location", new GeoPoint(params.getLocation()))
+ .order(SortOrder.ASC)
+ .unit(DistanceUnit.KILOMETERS)
+ );
+ }
+ try {
+ SearchResponse response = client.search(request, RequestOptions.DEFAULT);
+ return handleResponse(response);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void paramCheck(RequestParams params, BoolQueryBuilder boolQuery) {
+ if (StringUtils.isEmpty(params.getKey())) {
+ boolQuery.must(QueryBuilders.matchAllQuery());
+ } else {
+ boolQuery.must(QueryBuilders.matchQuery("all", params.getKey()));
+ }
+
+ if (StringUtils.isEmpty(params.getCity())) {
+ boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
+ }
+
+ if (StringUtils.isEmpty(params.getStarName())) {
+ boolQuery.filter(QueryBuilders.termQuery("city", params.getSize()));
+ }
+
+ if (params.getMinPrice() != null && params.getMaxPrice() != null) {
+ boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
+ }
+ }
+
+ private PageResult handleResponse(SearchResponse response) throws IOException {
+
+ SearchHit[] searchHits = response.getHits().getHits();
+ long total = response.getHits().getTotalHits().value;
+ List hotelDocList = new ArrayList<>();
+ for (SearchHit searchHit : searchHits) {
+ String source = searchHit.getSourceAsString();
+ HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
+ Object[] sortValues = searchHit.getSortValues();
+ hotelDoc.setDistance(ObjectUtils.isEmpty(sortValues) ? null : sortValues[0]);
+
+ hotelDocList.add(hotelDoc);
+ }
+ return new PageResult(total, hotelDocList);
+ }
}
diff --git a/src/test/java/cn/itcast/hotel/HotelDocumentTest.java b/src/test/java/cn/itcast/hotel/HotelDocumentTest.java
index bf7f8e0..83e51be 100644
--- a/src/test/java/cn/itcast/hotel/HotelDocumentTest.java
+++ b/src/test/java/cn/itcast/hotel/HotelDocumentTest.java
@@ -21,7 +21,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import javax.annotation.Resource;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
@SpringBootTest
@@ -29,84 +31,63 @@ class HotelDocumentTest {
private RestHighLevelClient client;
- @Autowired
+ @Resource
private IHotelService hotelService;
@Test
void testAddDocument() throws IOException {
- // 1.查询数据库hotel数据
- Hotel hotel = hotelService.getById(61083L);
- // 2.转换为HotelDoc
+ Hotel hotel = hotelService.getById(56227L);
HotelDoc hotelDoc = new HotelDoc(hotel);
- // 3.转JSON
- String json = JSON.toJSONString(hotelDoc);
-
- // 1.准备Request
- IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
- // 2.准备请求参数DSL,其实就是文档的JSON字符串
- request.source(json, XContentType.JSON);
- // 3.发送请求
+ IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
+ request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
+ // 发送请求
client.index(request, RequestOptions.DEFAULT);
}
@Test
- void testGetDocumentById() throws IOException {
- // 1.准备Request // GET /hotel/_doc/{id}
- GetRequest request = new GetRequest("hotel", "61083");
- // 2.发送请求
+ void testGetDocument() throws IOException {
+ GetRequest request = new GetRequest("hotel", "56227");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
- // 3.解析响应结果
- String json = response.getSourceAsString();
-
- HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
- System.out.println("hotelDoc = " + hotelDoc);
+ String source = response.getSourceAsString();
+ HotelDoc hotel = JSON.parseObject(source, HotelDoc.class);
+ System.out.println("hotel = " + hotel);
}
@Test
- void testDeleteDocumentById() throws IOException {
- // 1.准备Request // DELETE /hotel/_doc/{id}
- DeleteRequest request = new DeleteRequest("hotel", "61083");
- // 2.发送请求
- client.delete(request, RequestOptions.DEFAULT);
- }
-
- @Test
- void testUpdateById() throws IOException {
- // 1.准备Request
- UpdateRequest request = new UpdateRequest("hotel", "61083");
- // 2.准备参数
- request.doc(
- "price", "870"
+ void testUpdateDocument() throws IOException {
+ UpdateRequest updateRequest = new UpdateRequest("hotel", "56227");
+ updateRequest.doc(
+ "price", "999",
+ "starName", "四钻"
);
- // 3.发送请求
- client.update(request, RequestOptions.DEFAULT);
+ client.update(updateRequest, RequestOptions.DEFAULT);
}
@Test
- void testBulkRequest() throws IOException {
- // 查询所有的酒店数据
- List list = hotelService.list();
+ void testDeleteDocument() throws IOException {
+ DeleteRequest deleteRequest = new DeleteRequest("hotel", "56227");
+ client.delete(deleteRequest, RequestOptions.DEFAULT);
+ }
- // 1.准备Request
- BulkRequest request = new BulkRequest();
- // 2.准备参数
- for (Hotel hotel : list) {
- // 2.1.转为HotelDoc
+
+ @Test
+ void testBulkDocument() throws IOException {
+ BulkRequest bulkRequest = new BulkRequest();
+ List hotelList = hotelService.list();
+ for (Hotel hotel : hotelList) {
HotelDoc hotelDoc = new HotelDoc(hotel);
- // 2.2.转json
- String json = JSON.toJSONString(hotelDoc);
- // 2.3.添加请求
- request.add(new IndexRequest("hotel").id(hotel.getId().toString()).source(json, XContentType.JSON));
+ bulkRequest.add(new IndexRequest("hotel")
+ .id(hotelDoc.getId().toString())
+ .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
}
+ client.bulk(bulkRequest, RequestOptions.DEFAULT);
- // 3.发送请求
- client.bulk(request, RequestOptions.DEFAULT);
}
@BeforeEach
void setUp() {
client = new RestHighLevelClient(RestClient.builder(
- HttpHost.create("http://192.168.150.101:9200")
+ HttpHost.create("http://192.168.249.131:9200")
));
}
diff --git a/src/test/java/cn/itcast/hotel/HotelQueryTest.java b/src/test/java/cn/itcast/hotel/HotelQueryTest.java
new file mode 100644
index 0000000..caf5dea
--- /dev/null
+++ b/src/test/java/cn/itcast/hotel/HotelQueryTest.java
@@ -0,0 +1,126 @@
+package cn.itcast.hotel;
+
+import cn.itcast.hotel.pojo.Hotel;
+import cn.itcast.hotel.pojo.HotelDoc;
+import com.alibaba.fastjson.JSON;
+import org.apache.http.HttpHost;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.text.Text;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
+import org.elasticsearch.search.sort.SortOrder;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.BeanUtils;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.util.Map;
+
+@SpringBootTest
+public class HotelQueryTest {
+ private RestHighLevelClient client;
+
+ @Test
+ void testMatchAll() throws IOException {
+// 准备Request
+ SearchRequest request = new SearchRequest("hotel");
+// 准备DSL
+ request.source().query(QueryBuilders.matchAllQuery());
+// 发送请求
+ handleResponse(request);
+ }
+
+ @Test
+ void testMatch() throws IOException {
+// 准备Request
+ SearchRequest request = new SearchRequest("hotel");
+// 准备DSL
+ request.source().query(QueryBuilders.matchQuery("all", "如家"));
+ handleResponse(request);
+ }
+
+ @Test
+ void testTerm() throws IOException {
+ SearchRequest request = new SearchRequest("hotel");
+ request.source().query(QueryBuilders.termQuery("city", "成都"));
+ handleResponse(request);
+ }
+
+ @Test
+ void testBoolean() throws IOException {
+ SearchRequest request = new SearchRequest("hotel");
+ BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
+ boolQueryBuilder.must().add(QueryBuilders.termQuery("city", "上海"));
+ boolQueryBuilder.filter().add(QueryBuilders.rangeQuery("price").lte(999));
+ handleResponse(request);
+ }
+
+ @Test
+ void testPageAndSort() throws IOException {
+ SearchRequest request = new SearchRequest("hotel");
+ int page = 2;
+ int pageSize = 5;
+ request.source().query(QueryBuilders.matchAllQuery());
+ request.source().sort("price", SortOrder.ASC);
+ request.source().from((page - 1) * pageSize).size(pageSize);
+ handleResponse(request);
+ }
+
+
+ @Test
+ void testHighlight() throws IOException {
+ SearchRequest request = new SearchRequest("hotel");
+ request.source().query(QueryBuilders.matchQuery("all", "如家"));
+ request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
+ handleResponse(request);
+ }
+
+ private void handleResponse(SearchRequest request) throws IOException {
+ // 发送请求
+ SearchResponse response = client.search(request, RequestOptions.DEFAULT);
+ SearchHit[] searchHits = response.getHits().getHits();
+
+ for (SearchHit searchHit : searchHits) {
+ String source = searchHit.getSourceAsString();
+ Map highlightFields = searchHit.getHighlightFields();
+ if (!CollectionUtils.isEmpty(highlightFields)) {
+ HighlightField field = highlightFields.get("name");
+ Text[] texts = field.getFragments();
+ System.out.println(texts[0].string());
+ }
+ HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
+ Hotel hotel = new Hotel();
+ BeanUtils.copyProperties(hotelDoc, hotel);
+ String[] location = hotelDoc.getLocation().split(",");
+ hotel.setLatitude(location[0]);
+ hotel.setLongitude(location[1]);
+ System.out.println(hotel);
+ }
+ }
+
+
+
+
+
+ @BeforeEach
+ void setUp() {
+ client = new RestHighLevelClient(RestClient.builder(
+ HttpHost.create("http://192.168.249.131:9200")
+ ));
+ }
+
+ @AfterEach
+ void tearDown() throws IOException {
+ client.close();
+ }
+}