知乎專欄 | 多維度架構 | | | 微信號 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); } } } }