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 extends ElasticsearchCrudRepository {  

    S index(S var1);  

   Iterable search(QueryBuilder var1);  

   Page search(QueryBuilder var1, Pageable var2);  

   Page search(SearchQuery var1);  

   Page searchSimilar(T var1, String[] var2, Pageable var3);  

   void refresh();  

   Class getEntityClass();  

}  

编写自己的Resository操作类

public interface ArticleSearchRepository extends ElasticsearchRepository{

   List 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: 写入

    *

    * @author guooo Date:2017年9月27日下午3:20:06

    * @param article

    * @return

    * @since JDK 1.6

    */

   long saveArticle(Article article);

   /**

    * deleteArticle: 删除,并未真正删除,只是查询不到

    *

    * @author guooo Date:2017年9月27日下午3:20:08

    * @param id

    * @since JDK 1.6

    */

   void deleteArticle(long id);

   /**

    * findArticle:

    *

    * @author guooo Date:2017年9月27日下午3:20:10

    * @param id

    * @return

    * @since JDK 1.6

    */

   Article findArticle(long id);

   /**

    * findArticlePageable:

    *

    * @author guooo Date:2017年9月27日下午3:20:13

    * @return

    * @since JDK 1.6

    */

   List findArticlePageable();

   /**

    * findArticleAll:

    *

    * @author guooo Date:2017年9月27日下午3:20:15

    * @return

    * @since JDK 1.6

    */

   List findArticleAll();

   /**

    * findArticleSort:

    *

    * @author guooo Date:2017年9月27日下午3:20:18

    * @return

    * @since JDK 1.6

    */

   List findArticleSort();

   /**

    * search:

    *

    * @author guooo Date:2017年9月27日下午3:20:22

    * @param content

    * @return

    * @since JDK 1.6

    */

   List search(String content);

   /**

    * update: es没有修改操作,结合save操作完成

    *

    * @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 findArticlePageable() {

       return repository.findAll(pageable).getContent();

   }

   @Override

   public List findArticleAll() {

       Iterable iterables = repository.findAll();

       List articles = new ArrayList<>();

       for (Article article : iterables) {

           articles.add(article);

       }

       return articles;

   }

   @Override

   public List findArticleSort() {

       List orders = new ArrayList<>();

       Order order = new Order(Direction.ASC, "clickCount");

       orders.add(order);

       Sort sort = new Sort(orders);

       Iterable iterables = repository.findAll(sort);

       List articles = new ArrayList<>();

       for (Article article : iterables) {

           articles.add(article);

       }

       return articles;

   }

   @Override

   public List 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 findArticlePageable() {

       return articleService.findArticlePageable();

   }

   @RequestMapping(value = "findArticleAll", method = RequestMethod.POST)

   public List findArticleAll() {

       return articleService.findArticleAll();

   }

   @RequestMapping(value = "findArticleSort", method = RequestMethod.POST)

   public List findArticleSort() {

       return articleService.findArticleSort();

   }

   @RequestMapping(value = "search", method = RequestMethod.POST)

   public List 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 实现索引批量写入

Nginx+Lua+MySQL/Redis实现高性能动态网页展现

Nginx+Lua+Redis实现高性能缓存数据读取

基于SpringCloud的Microservices架构实战案例-序篇

介绍几款常用的在线API管理工具

野蛮生长的前端,从杂牌军到正规军

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提...
    MavenTalk阅读 12,382评论 0 0
  • 一步一步的搭建JAVA WEB项目,采用Maven构建,基于MYBatis+Spring+Spring MVC+B...
    叶子的翅膀阅读 12,665评论 5 25
  • 1:初心|遇见你 2:笔记|你知道写作吗(一) 3:笔记|你知道写作吗(二) 4:《如何有效阅读一本书》——你知道...
    鱼十七123阅读 322评论 3 1
  • 最后一次给你讲我听过的故事 她挽着他的手臂,他给她披上大衣 脸上的皱纹笑开了花,白发里夹杂着雪花 两个佝偻的影子在...
    夜枝阅读 152评论 0 4