Spring Boot + Elasticsearch 实现索引的日常维护
全文检索的应用越来越广泛,几乎成了互联网应用的标配,商品搜索、日志分析、历史数据归档等等,各种场景都会涉及到大批量的数据,在全文检索方面,方案无外乎Lucene、Solr、Elasticsearch三种应用的较为广泛。es、solr的底层都依托于Lucene,但es比solr学习成本更低,由于其提供的RESTful API简单快捷,对互联网应用开发而言更是如虎添翼。
下面结合以实际案例,通过Java API的形式操作es数据集。
框架选型基础是Spring Boot + Spring-data-elasticsearch + elasticsearch。
使用ElasticsearchRepository的形式来连接、维护ES数据集,ElasticsearchRepository中提供了简单的操作索引数据的方法集合,继承自ElasticsearchCrudRepository,涵盖了CRUD、排序、分页等常见的基本操作功能。
@NoRepositoryBean
public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {
<S extends T> S index(S var1);
Iterable<T> search(QueryBuilder var1);
Page<T> search(QueryBuilder var1, Pageable var2);
Page<T> search(SearchQuery var1);
Page<T> searchSimilar(T var1, String[] var2, Pageable var3);
void refresh();
Class<T> getEntityClass();
}
从基本的pom配置开始
<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.esp.index.data</groupId>
<artifactId>esp-cube</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.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.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</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-log4j</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>esp-cube</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
编写自己的Resository操作类
public interface ArticleSearchRepository extends ElasticsearchRepository<Article, Long>{
List<Article> findByAbstractsAndContent(String abstracts, String content);
}
其中Article为是与elasticsearch连接的实体类,类似于PO的概念,其中指定的索引名称、类型名称、及分片、副本数量等要素。
@Data
@Document(indexName = "article_index", type = "article", shards = 5, replicas = 1, indexStoreType = "fs", refreshInterval = "-1")
public class Article implements Serializable {
/**
* serialVersionUID:
*
* @since JDK 1.6
*/
private static final long serialVersionUID = 1L;
@Id
private Long id;
/** 标题 */
private String title;
/** 摘要 */
private String abstracts;
/** 内容 */
private String content;
/** 发表时间 */
@Field(format = DateFormat.date_time, index = FieldIndex.no, store = true, type = FieldType.Object)
private Date postTime;
/** 点击率 */
private Long clickCount;
}
我们需要定义域的实体和一个Spring data的基本的CRUD支持库类。用id注释定义标识符字段,如果你没有指定ID字段,Elasticsearch不能索引你的文件。同时需要指定索引名称类型,@Document注解也有助于我们设置分片和副本数量。
接口类
public interface ArticleService {
/**
* saveArticle: 写入<br/>
*
* @author guooo Date:2017年9月27日下午3:20:06
* @param article
* @return
* @since JDK 1.6
*/
long saveArticle(Article article);
/**
* deleteArticle: 删除,并未真正删除,只是查询不到<br/>
*
* @author guooo Date:2017年9月27日下午3:20:08
* @param id
* @since JDK 1.6
*/
void deleteArticle(long id);
/**
* findArticle: <br/>
*
* @author guooo Date:2017年9月27日下午3:20:10
* @param id
* @return
* @since JDK 1.6
*/
Article findArticle(long id);
/**
* findArticlePageable: <br/>
*
* @author guooo Date:2017年9月27日下午3:20:13
* @return
* @since JDK 1.6
*/
List<Article> findArticlePageable();
/**
* findArticleAll: <br/>
*
* @author guooo Date:2017年9月27日下午3:20:15
* @return
* @since JDK 1.6
*/
List<Article> findArticleAll();
/**
* findArticleSort: <br/>
*
* @author guooo Date:2017年9月27日下午3:20:18
* @return
* @since JDK 1.6
*/
List<Article> findArticleSort();
/**
* search: <br/>
*
* @author guooo Date:2017年9月27日下午3:20:22
* @param content
* @return
* @since JDK 1.6
*/
List<Article> search(String content);
/**
* update: es没有修改操作,结合save操作完成<br/>
*
* @author guooo Date:2017年9月27日下午3:20:25
* @param id
* @return
* @since JDK 1.6
*/
long update(long id);
}
接口实现
@Service
public class ArticleServiceImpl implements ArticleService {
final int page = 0;
final int size = 10;
/* 搜索模式 */
String SCORE_MODE_SUM = "sum"; // 权重分求和模式
Float MIN_SCORE = 10.0F; // 由于无相关性的分值默认为 1 ,设置权重分最小值为 10
Pageable pageable = new PageRequest(page, size);
@Autowired
ArticleSearchRepository repository;
@Override
public long saveArticle(Article article) {
Article result = repository.save(article);
return result.getId();
}
@Override
public void deleteArticle(long id) {
repository.delete(id);
}
@Override
public Article findArticle(long id) {
return repository.findOne(id);
}
@Override
public List<Article> findArticlePageable() {
return repository.findAll(pageable).getContent();
}
@Override
public List<Article> findArticleAll() {
Iterable<Article> iterables = repository.findAll();
List<Article> articles = new ArrayList<>();
for (Article article : iterables) {
articles.add(article);
}
return articles;
}
@Override
public List<Article> findArticleSort() {
List<Order> orders = new ArrayList<>();
Order order = new Order(Direction.ASC, "clickCount");
orders.add(order);
Sort sort = new Sort(orders);
Iterable<Article> iterables = repository.findAll(sort);
List<Article> articles = new ArrayList<>();
for (Article article : iterables) {
articles.add(article);
}
return articles;
}
@Override
public List<Article> search(String content) {
return repository.findByAbstractsAndContent(content, content);
}
@Override
public long update(long id) {
Article article = repository.findOne(id);
article.setTitle("test");
Article retun = repository.save(article);
System.out.println(retun.getId()+"更新的数据");
return retun.getId();
}
}
是不是与JPA、hibernate操作数据集的手法很类似?
controller方法类:
@RestController
@RequestMapping(value = "/article")
public class APIArticleController {
@Autowired
ArticleService articleService;
@RequestMapping(value = "save", method = RequestMethod.POST)
public long save() {
for (int i = 10000; i < 12000; i++) {
Article article = new Article();
article.setClickCount(Long.valueOf(i + RandomUtils.nextInt(23, i)));
article.setAbstracts("我的一个测试" + i);
article.setContent(i + "这是第一个测试的内容@spring-data-elasticsearch");
article.setPostTime(new Date());
article.setId(Long.valueOf(RandomUtils.nextLong(i, i)));
long _id = articleService.saveArticle(article);
System.out.println(_id);
}
return 23;
}
@RequestMapping(value = "delete", method = RequestMethod.POST)
public void deleteArticle(long id) {
articleService.deleteArticle(id);
}
@RequestMapping(value = "findOne", method = RequestMethod.POST)
public Article findArticle(long id) {
return articleService.findArticle(id);
}
@RequestMapping(value = "findArticlePageable", method = RequestMethod.POST)
public List<Article> findArticlePageable() {
return articleService.findArticlePageable();
}
@RequestMapping(value = "findArticleAll", method = RequestMethod.POST)
public List<Article> findArticleAll() {
return articleService.findArticleAll();
}
@RequestMapping(value = "findArticleSort", method = RequestMethod.POST)
public List<Article> findArticleSort() {
return articleService.findArticleSort();
}
@RequestMapping(value = "search", method = RequestMethod.POST)
public List<Article> search(String content) {
return articleService.search(content);
}
@RequestMapping(value = "update", method = RequestMethod.POST)
public long update(long id) {
return articleService.update(id);
}
}
Spring Boot的启动类及配置项,这里略过,项目启动后,可能过controller暴露出来的方法进行Article数据索引的CRUD操作
Spring Boot + Elasticsearch 实现索引的日常维护的更多相关文章
- Spring Boot + Elasticsearch 实现索引批量写入
在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提到的维护方法的话显然效率是低下的,此时推荐使用bulkIndex来提升效率.批写入数据 ...
- Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析
缘由 数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询. 技术方案 考虑 ...
- 搭建spring boot+elasticsearch+activemq服务
目前时间是:2017-01-24 本文不涉及activemq的安装 需求 activemq实时传递数据至服务 elasticsearch做索引 对外开放查询接口 完成全文检索 环境 jdk:1.8 s ...
- Spring Boot + Elasticsearch
spring data elasticsearch elasticsearch 2.0.0.RELEASE 2.2.0 1.4.0.M1 1.7.3 1.3.0.RELEASE 1.5.2 1.2.0 ...
- Spring Boot + Elasticsearch 使用示例
本文分别使用 Elasticsearch Repository 和 ElasticsearchTemplate 实现 Elasticsearch 的简单的增删改查 一.Elastic Stack El ...
- 。。。。。。不带http https : 不报错 spring boot elasticsearch rest
......不带http https : 不报错 先telnet http://onf:8080/getES653/道路桥梁正在“理疗”%20这14条道路纳入市政中修 @GetMapping(&qu ...
- spring data elasticsearch多索引查询
一次查询多个索引数据 es里可以这样写 GET 索引1,索引2,索引3/_search 也可以这样 给索引创建别名,多个索引可以使用一个别名 POST /_aliases { "action ...
- Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 预见未来最好的方式就是亲手创造未来 – <史蒂夫·乔布斯传> 』 运行环境: ...
- Spring Boot 太狠了,一次性发布了 3 个版本!
Spring Boot 太狠了,北京时间 2020/07/25 今天一次性发布了三个主要版本,三条版本线同时更新: Spring Boot 2.3.2 Spring Boot 2.2.9 Spring ...
随机推荐
- NetCore 上传,断点续传,可支持流上传
之前公司要做一个断点续传的业务,找了许多都没有找到合适的,都是残次不全的,终于让我遇到一个基于百度的 webuploader 的断点续传.原作者: 断点续传(上传)( https://www.some ...
- How do you create a DynamicResourceBinding that supports Converters, StringFormat?
原文 How do you create a DynamicResourceBinding that supports Converters, StringFormat? 2 down vote ac ...
- Python编写AWS Version 4 signing (AWS4-HMAC-SHA256) for execute-api
官网教程中给了签署AWS请求给了详细的介绍和python的例子,但是例子针对DynamoDB API,本例子针对API Gateway的POST请求,并携带有x-amz-security-token. ...
- WPF:通过BitmapSource的CopyPixels和Create方法来切割图片
原文 WPF:通过BitmapSource的CopyPixels和Create方法来切割图片 BitmapSource是WPF图像的最基本类型,它同时提供两个像素相关的方法就是CopyPixels和C ...
- C# WebRequest POST上传数据
WebRequest request = WebRequest.Create("http://www.cnsos.net"); // Set the Method property ...
- FMX App的Application的事件(各种手机的全局按键)
直接上代码,还有条经验就是SetApplicationEventHandler可注册多个事件方法. unit Unit6; interface uses System.SysUtils, Syste ...
- IntelliJ IDEA的jsp中内置对象方法无法被解析的解决办法
主要原因是因为缺乏依赖 可以通过添加依赖的方式 导入servlet-api.jar,jsp-api.jar,tomcat-api.jar 这三个jar即可 这三个jar在tomcat的lib目录下有 ...
- UTM (Urchin Tracking Module) codes
UTM Codes are a great way to see the results of your offline marketing In today’s day and age, we ar ...
- sqlserver/mysql按天,按小时,按分钟统计连续时间段数据
文 | 子龙 有技术,有干货,有故事的斜杠青年 一,写在前面的话 最近公司需要按天,按小时查看数据,可以直观的看到时间段的数据峰值.接到需求,就开始疯狂百度搜索,但是搜索到的资料有很多都不清楚,需要自 ...
- Scala 学习之路(三)—— 流程控制语句
一.条件表达式if Scala中的if/else语法结构与Java中的一样,唯一不同的是,Scala中的if表达式是有返回值的. object ScalaApp extends App { val x ...