第一步添加maven依赖
<?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>com.xxx.xxx.hot</groupId>
<artifactId>data-hot-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>data-hot-service</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jackson.version>2.8.8</jackson.version>
<guava.version>25.1-jre</guava.version>
<ant.version>1.9.4</ant.version>
<aspectj.version>1.8.10</aspectj.version>
<joda-time.varsion>2.9.9</joda-time.varsion>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- elasticsearch启动器 (必须)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--添加jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.varsion}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>${ant.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>development</id>
<name>maven-central</name>
<url>http://192.168.23.107:8081/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
第二步 继承ElasticsearchRepository接口
public interface ArticleRepository extends ElasticsearchRepository<SearchModel,String> {
}
第三步 创建实体
@Data
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@Document(indexName = "smas_weixin", type = "weixin", shards = 5, replicas = 1)
public class SearchModel {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
private String irAbstract;//摘要
//注意:Field属性需要和ElasticSearch里面的配置相同,否则,不能查询出数据
@Field(type = FieldType.Keyword, fielddata = true)
private String irChannel;
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
private String irContent;
@Field(type = FieldType.Text)
private String irDetailPage;
@Field(type = FieldType.Text)
private String irGzh2ImgUrl;
@Field(type = FieldType.Text)
private String irImageUrl;
@Field(type = FieldType.Text)
private String irSiteName;
@Field(type = FieldType.Keyword,fielddata = true)
private String irUrlTime;
@Field(type = FieldType.Text)
private String irUrlName;
@Field(type = FieldType.Text)
private String irUrlDate;
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
private String irUrlTitle;
private String all;
private int pageSize;//每页大小
private int pageIndex;//当前页
private long total;//总条数
private int totalPages;//总页数
}
第四步 controller
public class ArticleSearchController {
private static final Logger logger = LoggerFactory.getLogger(ArticleSearchController.class);
private final String AGGREGARION_STR = "channels";
@Autowired
private ArticleRepository articleRepository;
/**
* 分组查询文章公众号列表
*/
@RequestMapping("/channel/list")
public String searchChannels(){
logger.debug("=========>开始查询文章公众号列表.");
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
queryBuilder.addAggregation(AggregationBuilders.terms(AGGREGARION_STR).field("irChannel").size(Integer.MAX_VALUE));
AggregatedPage<SearchModel> aggChannels = (AggregatedPage<SearchModel>)articleRepository.search(queryBuilder.build());
StringTerms stringTerms = (StringTerms)aggChannels.getAggregation(AGGREGARION_STR);
List<StringTerms.Bucket> bucketList = stringTerms.getBuckets();
List<ArticleModel> articleList = new ArrayList<>();
bucketList.forEach(bucket ->{
ArticleModel article = new ArticleModel();
article.setChannel(bucket.getKeyAsString());
article.setArticlesCount(bucket.getDocCount());
articleList.add(article);
});
articleList.sort(Comparator.comparingLong(ArticleModel::getArticlesCount));
String channelsJson = JsonUtil.ObjectToJson(articleList);
logger.debug("=========>公众号列表::{}",channelsJson);
logger.debug("=========>结束查询文章公众号列表.");
return channelsJson;
}
/**
* 分页查看文章列表
*/
@RequestMapping("/article/list")
public String articleList(@RequestBody String param){
logger.debug("=========>开始查询文章列表.");
logger.debug("=========>请求参数:{}",param);
NativeSearchQueryBuilder queryBuilder = getQueryBuilder(param);
Page<SearchModel> items = articleRepository.search(queryBuilder.build());
List<SearchModel> searchModelList = items.getContent();
searchModelList.forEach(index -> {
if(index.getIrContent().length() > 200){
index.setIrContent(index.getIrContent().substring(0,200));
}else{
index.setIrContent(index.getIrContent());
}
index.setPageIndex(items.getNumber());
index.setTotal(items.getTotalElements());
index.setTotalPages(items.getTotalPages());
});
String searchModelJson = JsonUtil.ObjectToJson(searchModelList);
logger.debug("======>查询数据结果:{}",searchModelJson);
logger.debug("=========>结束查询文章列表.");
return searchModelJson;
}
/**
* 查询条件
*/
public NativeSearchQueryBuilder getQueryBuilder(String param){
NativeSearchQueryBuilder queryBuilder = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
SearchModel searchModel = objectMapper.readValue(param,SearchModel.class);
queryBuilder = new NativeSearchQueryBuilder();
if(StringUtils.isNotBlank(searchModel.getIrChannel())){
queryBuilder.withQuery(QueryBuilders.matchQuery("irChannel", searchModel.getIrChannel()));
}else{
if(StringUtils.isNotBlank(searchModel.getAll())){
queryBuilder.withQuery(QueryBuilders.multiMatchQuery(searchModel.getAll(),"irUrlTitle",searchModel.getAll() ,"irContent" ));
}
if(StringUtils.isNotBlank(searchModel.getIrUrlTitle())){
queryBuilder.withQuery(QueryBuilders.matchQuery("irUrlTitle", searchModel.getIrUrlTitle()));
}
if(StringUtils.isNotBlank(searchModel.getIrContent())){
queryBuilder.withQuery(QueryBuilders.matchQuery("irContent", searchModel.getIrContent()));
}
}
queryBuilder.withSort(SortBuilders.fieldSort("irUrlTime.keyword").order(SortOrder.DESC));
int pageIndex = searchModel.getPageIndex();
int pageSize = 10;
queryBuilder.withPageable(PageRequest.of(pageIndex,pageSize));
return queryBuilder;
} catch (IOException e) {
logger.error("=========>json转换异常,错误:{}",e);
}
return null;
}
附加util
public class JsonUtil{
private static final Logger logger = LoggerFactory.getLogger(JsonUtil.class);
public static String ObjectToJson(Object obj){
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
logger.error("=========>json转换异常,错误:{}",e);
}
return "";
}
}
第五步 application.properties
server.port = 9030
#=========== 日志配置·简易(spring boot已经集成logback日志)=========
#controller层日志 WARN级别输出
#logging.level.com.ghy.ic.map.service=WARN
#mapper层 sql日志 DEBUG级别输出
#logging.level.com.ghy.ic.map.domain.mapper=DEBUG
logging.file=logs/spring-boot-logging.log
logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
#打印运行时sql语句到控制台
spring.jpa.show-sql=true
#==================== 日志配合·标准 ============================
logging.config=classpath:logback-boot.xml
## Elasticsearch配置文件(必须)
## 该配置和Elasticsearch的elasticsearch.yml中的配置信息有关cmd
#spring.data.elasticsearch.cluster-name=my-application
spring.data.elasticsearch.cluster-nodes=39.98.172.160:9300
#spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
elasticsearch的配置
GET /smas_weixin
PUT /smas_weixin
{
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1"
}
}
}
PUT /smas_weixin/_mapping/weixin
{
"properties": {
"irAbstract": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"irChannel": {
"type": "text",
"analyzer": "whitespace",
"fields": {"raw": {"type": "keyword"}},
"fielddata": true
},
"irContent": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"irDetailPage": {
"type": "text"
},
"irGzh2ImgUrl": {
"type": "text"
},
"irImageUrl": {
"type": "text"
},
"irSiteName": {
"type": "text"
},
"irUrlDate": {
"type": "text"
},
"irUrlName": {
"type": "text"
},
"irUrlTime": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"fielddata": true
},
"irUrlTitle": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
}
}
}