| 知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
內嵌 Elasticsearch 應用,你不需要一個 Elasticsearch 伺服器,啟動 Spring boot 即可使用 Elasticsearch 服務。
需要下面兩個依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <!-- com.sun.jna for elasticsearch --> <dependency> <groupId>com.sun.jna</groupId> <artifactId>jna</artifactId> <version>3.0.9</version> </dependency>
<?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.example</groupId> <artifactId>api</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>api</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/javax.persistence/persistence-api --> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.json/json --> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> </dependency> <!-- com.sun.jna for elasticsearch --> <dependency> <groupId>com.sun.jna</groupId> <artifactId>jna</artifactId> <version>3.0.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> </project>
spring.data.elasticsearch.repositories.enabled=true #spring.data.elasticsearch.cluster-name=elasticsearch #spring.data.elasticsearch.cluster-nodes=119.29.241.95:9200 spring.data.elasticsearch.local=false spring.data.elasticsearch.properties.transport.tcp.connect_timeout=60s spring.data.elasticsearch.properties.host=127.0.0.1 spring.data.elasticsearch.properties.port=9200 spring.data.elasticsearch.properties.path.home=/tmp
package com.example.api.domain.elasticsearch;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Id;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldIndex;
import org.springframework.data.elasticsearch.annotations.FieldType;
import com.fasterxml.jackson.annotation.JsonFormat;
@Document(indexName = "information", type = "article")
public class Article implements Serializable {
/**
*
*/
private static final long serialVersionUID = 8789505663320446079L;
@Id
private int id;
private String title;
private String description;
private String author;
private String source;
private String content;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyyMMdd'T'HHmmss.SSS'Z'")
@Field(type = FieldType.Date, format = DateFormat.basic_date_time, index = FieldIndex.not_analyzed)
@CreatedDate
private Date ctime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getCtime() {
return ctime;
}
public void setCtime(Date ctime) {
this.ctime = ctime;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Article [id=" + id + ", title=" + title + ", description=" + description + ", author=" + author + ", source=" + source + ", content=" + content + ", ctime=" + ctime + "]";
}
}
package com.example.api.repository.elasticsearch;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import com.example.api.domain.elasticsearch.Article;
@Repository
public interface ArticleElasticsearchRepository extends ElasticsearchRepository<Article, Integer> {
Page<Article> findByTitleLike(String title, Pageable page);
Page<Article> findByDescription(String description, Pageable pageable);
Page<Article> findByDescriptionNot(String description, Pageable pageable);
Page<Article> findByDescriptionLike(String description, Pageable pageable);
}
package com.example.api.restful;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.api.domain.elasticsearch.Article;
import com.example.api.repository.elasticsearch.ArticleElasticsearchRepository;
@RestController
@RequestMapping("/restful/search")
public class SearchRestController {
@Autowired
private ArticleElasticsearchRepository articleElasticsearchRepository;
@RequestMapping(value = "/article/create")
public Article create() {
Article article = new Article();
article.setId(1);
article.setTitle("sssss");
article.setContent("test");
return articleElasticsearchRepository.save(article);
}
@RequestMapping(value = "/article/{articleId}")
public Article get(@PathVariable int articleId) {
return articleElasticsearchRepository.findOne(articleId);
}
}
MacBook-Pro:~ neo$ curl http://test:test@localhost:8443/restful/search/article/create.json
{"id":1,"title":"sssss","description":null,"author":null,"source":null,"content":"test","ctime":null}
MacBook-Pro:~ neo$ curl http://test:test@localhost:8443/restful/search/article/1.json
{"id":1,"title":"sssss","description":null,"author":null,"source":null,"content":"test","ctime":null}
查看 cluster.name 配置項
root@netkiller ~ % grep ^cluster.name /etc/elasticsearch/elasticsearch.yml cluster.name: elasticsearch
src/main/resources/application.properties
spring.data.elasticsearch.cluster-name=elasticsearch spring.data.elasticsearch.cluster-nodes=172.16.0.100:9200 spring.data.elasticsearch.local=false spring.data.elasticsearch.repositories.enabled=true
@Document(indexName = "customer", type = "external", shards = 1, replicas = 0, refreshInterval = "-1")
package com.example.api.schedule;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.rest.RestStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.example.api.domain.elasticsearch.ElasticsearchTrash;
import com.example.api.repository.elasticsearch.ElasticsearchTrashRepository;
@Component
public class ScheduledTasks {
private static final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
@Autowired
private TransportClient client;
@Autowired
private ElasticsearchTrashRepository alasticsearchTrashRepository;
public ScheduledTasks() {
}
@Scheduled(fixedRate = 1000 * 60) // 60秒運行一次調度任務
public void cleanTrash() {
for (ElasticsearchTrash elasticsearchTrash : alasticsearchTrashRepository.findAll()) {
DeleteResponse response = client.prepareDelete("information", "article", elasticsearchTrash.getId() + "").get();
RestStatus status = response.status();
logger.info("delete {} {}", elasticsearchTrash.getId(), status.toString());
if (status == RestStatus.OK || status == RestStatus.NOT_FOUND) {
alasticsearchTrashRepository.delete(elasticsearchTrash);
}
}
}
}