Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询

This commit is contained in:
JeffLi1993
2017-05-17 14:52:43 +08:00
committed by liqiangqiang
parent 9f7729abfc
commit 931cd7dbc0
8 changed files with 256 additions and 0 deletions

View File

@@ -39,6 +39,8 @@
<!-- Spring Boot 整合 Dubbo/ZooKeeper 详解 SOA 案例 --> <!-- Spring Boot 整合 Dubbo/ZooKeeper 详解 SOA 案例 -->
<module>springboot-dubbo-server</module> <module>springboot-dubbo-server</module>
<module>springboot-dubbo-client</module> <module>springboot-dubbo-client</module>
<!-- Spring Boot 整合 Elasticsearch -->
<module>springboot-elasticsearch</module>
</modules> </modules>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot</groupId>
<artifactId>springboot-elasticsearch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-elasticsearch :: 整合 Elasticsearch </name>
<!-- Spring Boot 启动父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot Elasticsearch 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- Spring Boot Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,20 @@
package org.spring.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Spring Boot 应用启动类
*
* Created by bysocket on 16/4/26.
*/
// Spring Boot 应用的标识
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 程序启动入口
// 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
SpringApplication.run(Application.class,args);
}
}

View File

@@ -0,0 +1,31 @@
package org.spring.springboot.controller;
import org.spring.springboot.domain.City;
import org.spring.springboot.service.CityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
/**
* 城市 Controller 实现 Restful HTTP 服务
* <p>
* Created by bysocket on 03/05/2017.
*/
@RestController
public class CityRestController {
@Autowired
private CityService cityService;
@RequestMapping(value = "/api/city", method = RequestMethod.POST)
public void createCity(@RequestBody City city) {
cityService.saveCity(city);
}
@RequestMapping(value = "/api/city/search", method = RequestMethod.GET)
public Page<City> searchCity(@RequestParam(value = "pageNumber") Integer pageNumber,
@RequestParam(value = "pageSize", required = false) Integer pageSize,
@RequestParam(value = "searchContent") String searchContent) {
return cityService.searchCity(pageNumber,pageSize,searchContent);
}
}

View File

@@ -0,0 +1,69 @@
package org.spring.springboot.domain;
import org.springframework.data.elasticsearch.annotations.Document;
import java.io.Serializable;
/**
* 城市实体类
*
* Created by bysocket on 03/05/2017.
*/
@Document(indexName = "cityIndex", type = "city")
public class City {
// implements Serializable
// private static final long serialVersionUID = -1L;
/**
* 城市编号
*/
private Long id;
/**
* 省份编号
*/
private Long provinceid;
/**
* 城市名称
*/
private String cityname;
/**
* 描述
*/
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getProvinceid() {
return provinceid;
}
public void setProvinceid(Long provinceid) {
this.provinceid = provinceid;
}
public String getCityname() {
return cityname;
}
public void setCityname(String cityname) {
this.cityname = cityname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@@ -0,0 +1,26 @@
package org.spring.springboot.service;
import org.spring.springboot.domain.City;
import org.springframework.data.domain.Page;
public interface CityService {
/**
* 新增城市信息
*
* @param city
* @return
*/
Long saveCity(City city);
/**
* 根据关键词function score query 权重分分页查询
*
* @param pageNumber
* @param pageSize
* @param searchContent
* @return
*/
Page<City> searchCity(Integer pageNumber, Integer pageSize, String searchContent);
}

View File

@@ -0,0 +1,66 @@
package org.spring.springboot.service.impl;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spring.springboot.domain.City;
import org.spring.springboot.repository.CityRepository;
import org.spring.springboot.service.CityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 城市 ES 业务逻辑实现类
*
* Created by bysocket on 07/02/2017.
*/
@Service
public class CityServiceImpl implements CityService {
private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class);
@Autowired
CityRepository cityRepository;
@Override
public Long saveCity(City city) {
City cityResult = cityRepository.save(city);
return cityResult.getId();
}
@Override
public Page<City> searchCity(Integer pageNumber,
Integer pageSize,
String searchContent) {
// 分页参数
// 按城市编号倒序
Pageable pageable = new PageRequest(pageNumber, pageSize, Sort.Direction.DESC, "id");
// Function Score Query
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery()
.add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("cityname", searchContent)),
ScoreFunctionBuilders.weightFactorFunction(1000))
.add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("description", searchContent)),
ScoreFunctionBuilders.weightFactorFunction(100));
// 创建搜索 DSL 查询
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withPageable(pageable)
.withQuery(functionScoreQueryBuilder).build();
LOGGER.info("\n searchCity(): searchContent [" + searchContent + "] \n DSL = \n " + searchQuery.getQuery().toString());
return cityRepository.search(searchQuery);
}
}

View File

@@ -0,0 +1,3 @@
# ES
spring.data.elasticsearch.repositories.enabled = true
spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300