zoukankan      html  css  js  c++  java
  • 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、排序、分页等常见的基本操作功能。

    1. @NoRepositoryBean  

    2. public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {  

    3.    <S extends T> S index(S var1);  

    4.    Iterable<T> search(QueryBuilder var1);  

    5.    Page<T> search(QueryBuilder var1, Pageable var2);  

    6.    Page<T> search(SearchQuery var1);  

    7.    Page<T> searchSimilar(T var1, String[] var2, Pageable var3);  

    8.    void refresh();  

    9.    Class<T> getEntityClass();  

    10. }  

    从基本的pom配置开始

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    2.    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    3.    <modelVersion>4.0.0</modelVersion>

    4.    <groupId>com.esp.index.data</groupId>

    5.    <artifactId>esp-cube</artifactId>

    6.    <version>0.0.1-SNAPSHOT</version>

    7.    <parent>

    8.        <groupId>org.springframework.boot</groupId>

    9.        <artifactId>spring-boot-starter-parent</artifactId>

    10.        <version>1.5.2.RELEASE</version>

    11.        <relativePath /> <!-- lookup parent from repository -->

    12.    </parent>

    13.    <properties>

    14.        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    15.        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    16.        <java.version>1.7</java.version>

    17.    </properties>

    18.    <dependencies>

    19.        <dependency>

    20.            <groupId>org.springframework.boot</groupId>

    21.            <artifactId>spring-boot-starter-jdbc</artifactId>

    22.            <exclusions>

    23.                <exclusion>

    24.                    <groupId>org.apache.tomcat</groupId>

    25.                    <artifactId>tomcat-jdbc</artifactId>

    26.                </exclusion>

    27.            </exclusions>

    28.        </dependency>

    29.        <dependency>

    30.            <groupId>org.springframework.boot</groupId>

    31.            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>

    32.        </dependency>

    33.        <dependency>

    34.            <groupId>org.springframework.boot</groupId>

    35.            <artifactId>spring-boot-starter-web</artifactId>

    36.            <exclusions>

    37.                <exclusion>

    38.                    <artifactId>log4j-over-slf4j</artifactId>

    39.                    <groupId>org.slf4j</groupId>

    40.                </exclusion>

    41.            </exclusions>

    42.        </dependency>

    43.        <dependency>

    44.            <groupId>org.springframework.boot</groupId>

    45.            <artifactId>spring-boot-starter</artifactId>

    46.            <exclusions>

    47.                <exclusion>

    48.                    <groupId>org.springframework.boot</groupId>

    49.                    <artifactId>spring-boot-starter-logging</artifactId>

    50.                </exclusion>

    51.            </exclusions>

    52.        </dependency>

    53.        <dependency>

    54.            <groupId>org.springframework.boot</groupId>

    55.            <artifactId>spring-boot-starter-test</artifactId>

    56.            <scope>test</scope>

    57.        </dependency>

    58.        <dependency>

    59.            <groupId>org.springframework.boot</groupId>

    60.            <artifactId>spring-boot-starter-log4j</artifactId>

    61.            <version>1.3.1.RELEASE</version>

    62.        </dependency>

    63.    </dependencies>

    64.    <build>

    65.        <finalName>esp-cube</finalName>

    66.        <plugins>

    67.            <plugin>

    68.                <groupId>org.springframework.boot</groupId>

    69.                <artifactId>spring-boot-maven-plugin</artifactId>

    70.            </plugin>

    71.        </plugins>

    72.    </build>

    73. </project>

    编写自己的Resository操作类

    1. public interface ArticleSearchRepository extends ElasticsearchRepository<Article, Long>{

    2.    List<Article> findByAbstractsAndContent(String abstracts, String content);

    3. }

    其中Article为是与elasticsearch连接的实体类,类似于PO的概念,其中指定的索引名称、类型名称、及分片、副本数量等要素。

    1. @Data

    2. @Document(indexName = "article_index", type = "article", shards = 5, replicas = 1, indexStoreType = "fs", refreshInterval = "-1")

    3. public class Article implements Serializable {

    4.    /**

    5.     * serialVersionUID:

    6.     *

    7.     * @since JDK 1.6

    8.     */

    9.    private static final long serialVersionUID = 1L;

    10.    @Id

    11.    private Long id;

    12.    /** 标题 */

    13.    private String title;

    14.    /** 摘要 */

    15.    private String abstracts;

    16.    /** 内容 */

    17.    private String content;

    18.    /** 发表时间 */

    19.    @Field(format = DateFormat.date_time, index = FieldIndex.no, store = true, type = FieldType.Object)

    20.    private Date postTime;

    21.    /** 点击率 */

    22.    private Long clickCount;

    23. }

    我们需要定义域的实体和一个Spring data的基本的CRUD支持库类。用id注释定义标识符字段,如果你没有指定ID字段,Elasticsearch不能索引你的文件。同时需要指定索引名称类型,@Document注解也有助于我们设置分片和副本数量。

    接口类

    1. public interface ArticleService {

    2.    /**

    3.     * saveArticle: 写入<br/>

    4.     *

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

    6.     * @param article

    7.     * @return

    8.     * @since JDK 1.6

    9.     */

    10.    long saveArticle(Article article);

    11.    /**

    12.     * deleteArticle: 删除,并未真正删除,只是查询不到<br/>

    13.     *

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

    15.     * @param id

    16.     * @since JDK 1.6

    17.     */

    18.    void deleteArticle(long id);

    19.    /**

    20.     * findArticle: <br/>

    21.     *

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

    23.     * @param id

    24.     * @return

    25.     * @since JDK 1.6

    26.     */

    27.    Article findArticle(long id);

    28.    /**

    29.     * findArticlePageable: <br/>

    30.     *

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

    32.     * @return

    33.     * @since JDK 1.6

    34.     */

    35.    List<Article> findArticlePageable();

    36.    /**

    37.     * findArticleAll: <br/>

    38.     *

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

    40.     * @return

    41.     * @since JDK 1.6

    42.     */

    43.    List<Article> findArticleAll();

    44.    /**

    45.     * findArticleSort: <br/>

    46.     *

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

    48.     * @return

    49.     * @since JDK 1.6

    50.     */

    51.    List<Article> findArticleSort();

    52.    /**

    53.     * search: <br/>

    54.     *

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

    56.     * @param content

    57.     * @return

    58.     * @since JDK 1.6

    59.     */

    60.    List<Article> search(String content);

    61.    /**

    62.     * update: es没有修改操作,结合save操作完成<br/>

    63.     *

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

    65.     * @param id

    66.     * @return

    67.     * @since JDK 1.6

    68.     */

    69.    long update(long id);

    70. }

    接口实现

    1. @Service

    2. public class ArticleServiceImpl implements ArticleService {

    3.    final int page = 0;

    4.    final int size = 10;

    5.    /* 搜索模式 */

    6.    String SCORE_MODE_SUM = "sum"; // 权重分求和模式

    7.    Float MIN_SCORE = 10.0F; // 由于无相关性的分值默认为 1 ,设置权重分最小值为 10

    8.    Pageable pageable = new PageRequest(page, size);

    9.    @Autowired

    10.    ArticleSearchRepository repository;

    11.    @Override

    12.    public long saveArticle(Article article) {

    13.        Article result = repository.save(article);

    14.        return result.getId();

    15.    }

    16.    @Override

    17.    public void deleteArticle(long id) {

    18.        repository.delete(id);

    19.    }

    20.    @Override

    21.    public Article findArticle(long id) {

    22.        return repository.findOne(id);

    23.    }

    24.    @Override

    25.    public List<Article> findArticlePageable() {

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

    27.    }

    28.    @Override

    29.    public List<Article> findArticleAll() {

    30.        Iterable<Article> iterables = repository.findAll();

    31.        List<Article> articles = new ArrayList<>();

    32.        for (Article article : iterables) {

    33.            articles.add(article);

    34.        }

    35.        return articles;

    36.    }

    37.    @Override

    38.    public List<Article> findArticleSort() {

    39.        List<Order> orders = new ArrayList<>();

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

    41.        orders.add(order);

    42.        Sort sort = new Sort(orders);

    43.        Iterable<Article> iterables = repository.findAll(sort);

    44.        List<Article> articles = new ArrayList<>();

    45.        for (Article article : iterables) {

    46.            articles.add(article);

    47.        }

    48.        return articles;

    49.    }

    50.    @Override

    51.    public List<Article> search(String content) {

    52.        return repository.findByAbstractsAndContent(content, content);

    53.    }

    54.    @Override

    55.    public long update(long id) {

    56.        Article article = repository.findOne(id);

    57.        article.setTitle("test");

    58.        Article retun = repository.save(article);

    59.        System.out.println(retun.getId()+"更新的数据");

    60.        return retun.getId();

    61.    }

    62. }

    是不是与JPA、hibernate操作数据集的手法很类似?

    controller方法类:

    1. @RestController

    2. @RequestMapping(value = "/article")

    3. public class APIArticleController {

    4.    @Autowired

    5.    ArticleService articleService;

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

    7.    public long save() {

    8.        for (int i = 10000; i < 12000; i++) {

    9.            Article article = new Article();

    10.            article.setClickCount(Long.valueOf(i + RandomUtils.nextInt(23, i)));

    11.            article.setAbstracts("我的一个测试" + i);

    12.            article.setContent(i + "这是第一个测试的内容@spring-data-elasticsearch");

    13.            article.setPostTime(new Date());

    14.            article.setId(Long.valueOf(RandomUtils.nextLong(i, i)));

    15.            long _id = articleService.saveArticle(article);

    16.            System.out.println(_id);

    17.        }

    18.        return 23;

    19.    }

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

    21.    public void deleteArticle(long id) {

    22.        articleService.deleteArticle(id);

    23.    }

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

    25.    public Article findArticle(long id) {

    26.        return articleService.findArticle(id);

    27.    }

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

    29.    public List<Article> findArticlePageable() {

    30.        return articleService.findArticlePageable();

    31.    }

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

    33.    public List<Article> findArticleAll() {

    34.        return articleService.findArticleAll();

    35.    }

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

    37.    public List<Article> findArticleSort() {

    38.        return articleService.findArticleSort();

    39.    }

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

    41.    public List<Article> search(String content) {

    42.        return articleService.search(content);

    43.    }

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

    45.    public long update(long id) {

    46.        return articleService.update(id);

    47.    }

    48. }

    Spring Boot的启动类及配置项,这里略过,项目启动后,可能过controller暴露出来的方法进行Article数据索引的CRUD操作




    成长的乐趣,在于分享!
    大龄程序员,一路走来,感慨颇多。闲暇时写写字,希望能给同行人一点帮助。
    本文版权归作者growithus和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    海康API——获取监控点预览取流URL,获取的rtsp流不能播放
    MySQL——ON DUPLICATE KEY UPDATE添加索引值实现重复插入变更update
    maven——pom.xml的Missing artifact net.sf.json-lib:json-lib:jar:2.4 报错问题(两种有效的解决方案)
    Mysql——navicat如何导出mysql数据表结构
    MySQL——导入导出.sql文件
    仅用U盘就可以去除XP管理员密码
    测试

    navicat 或者workbench 无法连接127.0.0.1(61)的解决方法
    在linux中添加ftp用户,并设置相应的权限
  • 原文地址:https://www.cnblogs.com/growithus/p/11012208.html
Copyright © 2011-2022 走看看