天天看點

elasticSearch叢集搭建---入門篇二

Elasticsearch(二)

elasticSearch安裝,基本操作,入門篇一

1 通過java用戶端對es維護

1.1 工程搭建

  • 建立maven工程
elasticSearch叢集搭建---入門篇二
  • 添加依賴,在pom.xml檔案添加如下依賴:
<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.24</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
           
  • 建立測試類ElasticSearchDemo
elasticSearch叢集搭建---入門篇二

1.2 索引操作

1.2.1 建立索引

在測試類中添加testCreateIndex方法:

為友善測試:在測試類中添加before和after方法,分别在測試方法前執行,建立用戶端連接配接對象,測試方法執行後執行,關閉資源

private Client client = null;
    @Before
    public void before() {
        client = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress(
                        new InetSocketAddress("localhost", 9300)));
    }

    @After
    public void after() {
        client.close();
    }
           
// 建立索引
    @Test
    public void testCreateIndex() {
        client.admin().indices().prepareCreate("blog3").get();
    }
           

1.2.2 删除索引

在測試類中添加testDeleteIndex方法:

//删除索引
    @Test
    public void testDeleteIndex() {
        client.admin().indices().prepareDelete("blog3").get();
    }

           

1.3 建立映射

1.3.1 建立映射前

這裡的映射表示建立索引類型結構,如果不建立映射,Elasticsearch會預設根據建立的文檔中的資料用來建立映射。檢視之前的blog3的映射。

elasticSearch叢集搭建---入門篇二

1.3.2 建立映射

在測試類中添加方法:

// 建立映射 注意建立映射時一定要有索引的存在,不然無法建立映射,
    // 映射就相當于表結構 建立表和表的結構時,必須要有資料庫(索引)
    @Test
   public void testCreateMapping1() throws Exception {
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();
        xContentBuilder
                .startObject()
                    .startObject("properties")
                        .startObject("id")
                            .field("type", "long")
                        .endObject()
                        .startObject("title")
                            .field("type", "text")
                            .field("store", false)
                            .field("analyzer", "ik_smart")
                        .endObject()
                        .startObject("content")
                            .field("type", "text")
                            .field("store", false)
                            .field("analyzer", "ik_smart")
                        .endObject()
                    .endObject()
                .endObject();

        PutMappingRequest mappingRequest = Requests.putMappingRequest("blog3").type("article").source(xContentBuilder);
        client.admin().indices().putMapping(mappingRequest);
    }
           

1.3.3 建立映射後

建立映射後的結果如下:

elasticSearch叢集搭建---入門篇二

1.4 文檔資料操作

1.4.1 建立文檔資料

1.4.1.1 通過XContentBuilder建立

通過XContentBuilder建構文檔資料。在測試中添加方法:

// 建立文檔資料
    @Test
    public void testCreateDocByXContentBuilder() throws IOException {
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                .startObject()
                .field("id", 2)
                .field("title", "學習路線")
                .field("content", "計算機組成原理、計算機網絡、資料結構、作業系統等")
                .endObject();
        client.prepareIndex("blog3","article","2").setSource(xContentBuilder).get();
    }
           

1.4.1.2 通過POJO建立

通過POJO建構文檔資料。在測試中添加方法:

  • 添加Jackson依賴(需要将pojo轉成json對象)
    <!--jackson JSON轉換包-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.1</version>
    </dependency>
               
  • 建立pojo,在src目錄下建立Article對象
package com.demo;

public class Article {

    private Integer id;
    private String title;
    private String content;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}
           
  • 編寫代碼
//根據bean建立文檔資料
    @Test
    public void testCreateDocByPojo() throws IOException {
        Article article = new Article();
        article.setId(3);
        article.setTitle("elasticSearch");
        article.setContent("elasticSearch時搜尋引擎服務,查詢速度快");
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] source = objectMapper.writeValueAsBytes(article);
        client.prepareIndex("blog3","article","3").setSource(source).get();
    }

           

1.4.2 更新文檔資料

1.4.2.1 通過prepareUpdate方法修改

在測試類添加方法:

//根據prepareUpdate更新文檔資料
    @Test
    public void testUpdateDoc() throws JsonProcessingException {
        Article article = new Article();
        article.setId(2);
        article.setTitle("java學習路線-更新了");
        article.setContent("需要學習資料結構、計算機網絡、計算機組成原理、作業系統等-更新了");
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] sources = objectMapper.writeValueAsBytes(article);
        client.prepareUpdate("blog3","article","2").setDoc(sources, XContentType.JSON).get();
    }
           

1.4.2.2 通過update方法修改

添加測試方法:

//根據update更新文檔資料
    @Test
    public void testUpdate() throws JsonProcessingException, ExecutionException, InterruptedException {
        Article article = new Article();
        article.setId(3);
        article.setTitle("elasticSearch--更新了");
        article.setContent("elasticSearch時搜尋引擎服務,查詢速度快--更新了");
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] bytes = objectMapper.writeValueAsBytes(article);
        UpdateRequest request = new UpdateRequest("blog3", "article", "3").doc(bytes,XContentType.JSON);
        client.update(request).get();
    }
           

1.4.3 删除文檔資料

//删除文檔
    @Test
    public void testDelte(){
        client.prepareDelete("blog3","article","3").get();
    }
           

1.4.4 批量增加資料

//批量增加資料
    @Test
    public void testBatchDocs() throws JsonProcessingException, ExecutionException, InterruptedException {
        BulkRequestBuilder bulk = client.prepareBulk();
        ObjectMapper objectMapper = new ObjectMapper();
        for (int i = 1; i <= 10; i++) {
            Article article = new Article();
            article.setId(i);
            article.setTitle("如何學好es"+i);
            article.setContent("了解Elasticsearch需要掌握反向索引,版本為:"+i);
            byte[] bytes = objectMapper.writeValueAsBytes(article);
            IndexRequestBuilder indexRequestBuilder = client.prepareIndex("blog3", "article", String.valueOf(i)).setSource(bytes, XContentType.JSON);
            bulk.add(indexRequestBuilder);
        }
        bulk.execute().get();
    }
           

1.5 查詢

1.5.1 根據字元串查詢

// 根據字元串查詢
    @Test
    public void testQueryByString() throws Exception {
        SearchResponse searchResponse = client.prepareSearch("blog3")
                                            .setTypes("article")
                                            .setQuery(QueryBuilders.queryStringQuery("反向索引"))// 根據字元串查詢
                                            .get();
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
           

1.5.2 根據詞條查詢

// 根據詞條查詢
    /*
    * IK分詞器,在建立索引的時候将英文都變成了小寫,這樣友善我們在搜尋的時候可以實作“不區分大小寫”的搜尋,
    * 是以在編寫程式時,是以我們在根據英文單詞查詢時,需要将大寫字母轉成小寫字母<toLowerCase()方法>
    * */
    @Test
    public void testQueryByTerm() throws Exception {
        SearchResponse searchResponse = client.prepareSearch("blog3")
                .setTypes("article")
                .setQuery(QueryBuilders.termQuery("content","Elasticsearch".toLowerCase()))//根據詞條查詢
                .get();
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
           

<http://127.0.0.1:9200/_analyze?analyzer=ik_max_word&pretty=true&text=ElasticSearch是一個全文檢索的架構>

elasticSearch叢集搭建---入門篇二

1.5.3 結果集處理

在上面的查詢中,擷取到的結果都是json對象,是以我們可以轉成pojo。在測試中添加方法:

//結果集處理
    @Test
    public void testQueryForResult() throws IOException {
        SearchResponse searchResponse = client.prepareSearch("blog3")
                .setTypes("article")
                .setQuery(QueryBuilders.termQuery("content", "Elasticsearch".toLowerCase()))
                .get();
        SearchHits hits = searchResponse.getHits();
        ArrayList<Article> articles = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        for (SearchHit hit : hits) {
            String source = hit.getSourceAsString();
            Article article = objectMapper.readValue(source, Article.class);
            articles.add(article);
        }
        for (Article article : articles) {
            System.out.println(article);
        }

    }
           

1.5.4 其他查詢實作

@Test
    public void testQueryByOtherCondition() throws Exception {
        SearchResponse searchResponse = client.prepareSearch("blog3")
                .setTypes("article")
                //.setQuery(QueryBuilders.queryStringQuery("反向索引"))// 字元串查詢
                //.setQuery(QueryBuilders.termQuery("title", "如何"))
                //.setQuery(QueryBuilders.termQuery("content","Elasticsearch".toLowerCase()))//根據詞條查詢
                //.setQuery(QueryBuilders.matchAllQuery())//查詢所有
                //.setQuery(QueryBuilders.wildcardQuery("content","?引"))//比對一個
                //.setQuery(QueryBuilders.wildcardQuery("content","*索引"))//零個或者多個
                //.setQuery(QueryBuilders.rangeQuery("id").from(1,true).to(5,true))//區間段查詢
                .setQuery(QueryBuilders.fuzzyQuery("content","elastiasaarch")) 相似度查詢,比對的錯誤字元個數[0,2]
                .get();
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
           

1.5.5 組合查詢

組合查詢:即添加多個條件。

must(QueryBuilders) : AND,求交集
 mustNot(QueryBuilders): NOT,求差集
 should(QueryBuilders):OR ,求并集
           
//組合查詢
    @Test
    public void testQueryByBoolean(){
        SearchResponse searchResponse = client.prepareSearch("blog3")
                .setTypes("article")
                .setQuery(QueryBuilders
                        .boolQuery()
                        .must(QueryBuilders.matchAllQuery())
                        .mustNot(QueryBuilders.rangeQuery("id")
                        .from(1, true).to(5, true))).get();
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

           

1.5.6 使用DSL表達式

使用restful風格程式設計,傳遞消息體,使用head插件檢視索引庫的資訊,進行查詢:

請求體:

{
  "query" : {
    "bool" : {
      "must" : {
        "term" : {
          "title" : "es"
        }
      },
      "must" : {
        "range" : {
          "id" : {
            "from" : 5,
            "to" : 55
          }
        }
      }
    }
  }
}
           
elasticSearch叢集搭建---入門篇二

1.5.7 分頁并排序

// 分頁并排序
    @Test
    public void test() throws IOException {
        // 調用查詢方法
        SearchResponse searchResponse = client.prepareSearch("blog3")
                .setTypes("article")
                .setQuery(QueryBuilders.matchAllQuery())
                .addSort("id", SortOrder.DESC)// 排序
                .setFrom(0) // 起始行=(目前頁碼 - 1)* 每頁顯示的條數
                .setSize(20) // 每頁顯示的條數
                .get();
        // 結果集處理
        SearchHits hits = searchResponse.getHits();
        System.out.println("查詢總數"+hits.getTotalHits());
        ObjectMapper objectMapper = new ObjectMapper();
        for (SearchHit hit : hits) {
            String source = hit.getSourceAsString();
            Article article = objectMapper.readValue(source, Article.class);
            System.out.println(article);

        }
    }

           

1.6 結果高亮顯示

1.6.1 概念

  • 高亮:在進行關鍵字搜尋時,搜尋出的内容中的關鍵字會顯示不同的顔色,稱之為高亮。
  • 高亮的本質:其始就對檢索到的結果集中包含的關鍵字添加HTML标簽,并且通過相關樣式進行修飾。

例如:

elasticSearch叢集搭建---入門篇二

1.6.2 代碼實作

//關鍵字高亮顯示
    @Test
    public void testQueryByHighLight(){

        //設定高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.field("title"); // 對哪個字段進行高亮
        //查詢
        SearchResponse searchResponse = client.prepareSearch("blog3")
                .setTypes("article")
                .setQuery(QueryBuilders.termQuery("title", "如何"))
                .addSort("id", SortOrder.ASC) // 排序
                .setFrom(0)// 起始行 = (目前頁碼 - 1) * 每頁顯示的條
                .setSize(20)// 每頁顯示的條數
                .highlighter(highlightBuilder)// 添加高亮條件
                .get();

        //結果集處理
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            HighlightField title = hit.getHighlightFields().get("title");
            Text[] fragments = title.getFragments();
            if (fragments!=null && fragments.length>0){
                System.out.println(fragments[0].toString());
            }

        }
    }
           
  • 效果如下:
elasticSearch叢集搭建---入門篇二

2 通過Spring Data對es內建

2.1 Spring Data介紹

Spring Data ElasticSearch 基于 spring data API 簡化 elasticSearch操作,将原始操作elasticSearch的用戶端API 進行封裝,通過ElasticsearchTemplate操作。Spring Data為Elasticsearch項目提供內建搜尋引擎。Spring Data Elasticsearch POJO的關鍵功能區域為中心的模型與Elastichsearch互動文檔和輕松地編寫一個存儲索引庫資料通路層。

2.2 Spring Data Elasticsearch入門

2.2.1 工程搭建

  • 建立工程:springdata_elasticSearch
    elasticSearch叢集搭建---入門篇二
  • 添加依賴:
<!--依賴包-->
<dependencies>
    <!--ES依賴包-->
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>5.6.8</version>
    </dependency>

    <!--日志依賴-->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.24</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>

    <!--測試包-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.0.8.RELEASE</version>
    </dependency>

    <!--springdata-es-->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>3.0.7.RELEASE</version>
    </dependency>
</dependencies>
           

2.2.2 增加索引資料

1、建立索引

2、建立映射

3、向索引庫中添加文檔資料

springdata內建es ElasticsearchTemplate

1、建立pojo:

  • 添加相關es注解

2、建立dao:需要繼承ElasticsearchRepository

3、編寫service:

4、編寫spring.xml檔案:管理 ElasticsearchTemplate

2.2.2.1 建立pojo

在工程的src目錄下建立Article。

package com.demo.pojo;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Document(indexName = "blog4",type = "article")
public class Article {
    @Id
    private Integer id;
    @Field(index = true,store = false,analyzer = "ik_smart",searchAnalyzer = "ik_smart",type = FieldType.Text)
    private String title;
    @Field(index = true,store = false,analyzer = "ik_smart",searchAnalyzer = "ik_smart",type = FieldType.Text)
    private String content;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

           

注解說明

@Document(indexName=“blob4”,type=“article”): 文檔與pojo映射
indexName:索引的名稱(必填項),type:索引的類型

@Id:主鍵的唯一辨別
@Field(index=true,store=true,analyzer=“ik_smart”,searchAnalyzer=“ik_smart”,type =FieldType.Text)
index:是否設定分詞
store:是否存儲,預設值是false。如果預設設定為false,Elasticsearch預設使用_source存放我們資料内容
analyzer:存儲時使用的分詞器
searchAnalyze:搜尋時使用的分詞器
type: 資料類型
           

2.2.2.2 編寫dao接口

在工程src目錄下,建立ArticleDao接口,需要繼承ElasticsearchRepository.

package com.demo.dao;

import com.demo.pojo.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface ArticleDao extends ElasticsearchRepository<Article,Integer> {
    
}

           

2.2.2.3 編寫service接口以及實作類

  • 編寫ArticleService接口
package com.demo.service;

import com.demo.pojo.Article;

public interface ArticleService {
    //添加資料
    void save(Article article);
}

           
  • 編寫ArticleServiceImpl實作類
package com.demo.service.impl;

import com.demo.dao.ArticleDao;
import com.demo.pojo.Article;
import com.demo.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleDao articleDao;
    
    @Override
    public void save(Article article) {
        articleDao.save(article);
    }
    
}

           

2.2.2.4 編寫spring.xml檔案

在resources目錄下建立spring.xml檔案:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/data/elasticsearch
      http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">

    <!--IoC容器:開啟注解掃描-->
    <context:component-scan base-package="com.demo.service"/>
    <!--掃描dao-->
    <elasticsearch:repositories base-package="com.demo.dao" />
    <!--配置es用戶端并且連接配接es服務-->
    <elasticsearch:transport-client id="client" cluster-nodes="localhost:9300" cluster-name="elasticsearch" />
    <!--ElasticSearch模版對象(底層使用模闆操作,需要用spring建立,并注入client)-->
    <bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
        <!--注入client-->
        <constructor-arg name="client" ref="client"/>
    </bean>
</beans>
           

2.2.2.5 單元測試

在test目錄下建立測試類:

package com.demo;

import com.demo.pojo.Article;
import com.demo.service.ArticleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@ContextConfiguration(locations = {"classpath:spring.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class EsTemplateDemo {
    @Autowired
    private ArticleService articleService;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    // 建立索引和映射
    @Test
    public void testCreateIndexAndMapping(){
        //建立索引
        elasticsearchTemplate.createIndex(Article.class);
        elasticsearchTemplate.putMapping(Article.class);
    }

    //測試添加資料
    @Test
    public void testSave(){
        Article article = new Article();
        article.setId(1);
        article.setTitle("什麼是es");
        article.setContent("Elasticsearch是一個全文檢索系統,并且是基于lucene開發");
        articleService.save(article);
    }
    
}

           
elasticSearch叢集搭建---入門篇二

2.3 對索引資料維護-CRUD

2.3.1 編寫service接口以及實作類

  • 編寫service接口:在接口中添加其他方法
public interface ArticleService {

    // 建立索引資料
    void save(Article article);

    // 批量儲存
    void saveAll(List<Article> articles);

    // 根據id删除:通過pojo封裝條件
    void delete(Article article);

    // 根據id删除
    void deleteById(Integer id);

    // 查詢所有
    Iterable<Article> findAll();

    // 分頁查詢
    Page<Article> findAll(Pageable pageable);
}
           
  • 編寫實作類:實作接口中的相關方法
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleDao articleDao;

    // 儲存索引資料
    public void save(Article article) {
        articleDao.save(article);
    }

    // 批量儲存
    public void saveAll(List<Article> articles) {
        articleDao.saveAll(articles);
    }

    // 根據id删除:通過pojo封裝條件
    public void delete(Article article) {
        articleDao.delete(article);
    }

    // 根據id删除
    public void deleteById(Integer id) {
        articleDao.deleteById(id);
    }

    // 查詢所有
    public Iterable<Article> findAll() {
        return articleDao.findAll();
    }

    public Page<Article> findAll(Pageable pageable) {
        return articleDao.findAll(pageable);
    }
}
           

2.3.2 編寫單元測試

在測試類中添加相關方法:

package com.demo;

import com.demo.pojo.Article;
import com.demo.service.ArticleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.ArrayList;
import java.util.List;

@ContextConfiguration(locations = {"classpath:spring.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class EsTemplateDemo {
    @Autowired
    private ArticleService articleService;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    // 建立索引和映射
    @Test
    public void testCreateIndexAndMapping(){
        //建立索引
        elasticsearchTemplate.createIndex(Article.class);
        elasticsearchTemplate.putMapping(Article.class);
    }

    //測試添加資料
    @Test
    public void testSave(){
        Article article = new Article();
        article.setId(1);
        article.setTitle("什麼是es");
        article.setContent("Elasticsearch是一個全文檢索系統,并且是基于lucene開發");
        articleService.save(article);
    }

    //測試批量添加
    @Test
    public void testSaveAll(){
        ArrayList<Article> articles = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            Article article = new Article();
            article.setId(i);
            article.setTitle("es版本"+i);
            article.setContent("spring data elasticsearch可以簡化原生api操作:" + i);
            articles.add(article);
        }
        articleService.saveAll(articles);
    }

    @Test
    public void update(){
        Article article = new Article();
        article.setId(1);
        article.setTitle("es版本更新1");
        article.setContent("spring data elasticsearch可以簡化原生api操作更新");
        articleService.save(article);
    }

    //根據id删除
    @Test
    public void delete(){
        Article article = new Article();
        article.setId(1);
        articleService.delete(article);
    }

    //根據id删除
    @Test
    public void deleteById(){
        articleService.deleteById(1);
    }

    //查詢所有
    @Test
    public void findAll(){
        Iterable<Article> articles = articleService.findAll();
        articles.forEach(article -> System.out.println(article));

    }

    //分頁查詢
    @Test
    public void findByPage(){
        //new PageRequest(getPageNumber() + 1, getPageSize(), getSort());
        PageRequest pageRequest = new PageRequest(0, 10, Sort.Direction.ASC, "id");
        Page<Article> articles = articleService.findByPage(pageRequest);
        System.out.println(articles.getTotalPages());//總頁數
        System.out.println(articles.getTotalElements());//總條數
        List<Article> list = articles.getContent();
        for (Article article : list) {
            System.out.println(article);
        }
    }
}

           

2.4 常用查詢命名規則

關鍵字 命名規則 解釋 示例
and findByField1AndField2 根據Field1和Field2獲得資料 findByTitleAndContent
or findByField1OrField2 根據Field1或Field2獲得資料 findByTitleOrContent
is findByField 根據Field獲得資料 findByTitle
not findByFieldNot 根據Field獲得補集資料 findByTitleNot
between findByFieldBetween 獲得指定範圍的資料 findByPriceBetween
lessThanEqual findByFieldLessThan 獲得小于等于指定值的資料 findByPriceLessThan

2.4.1 需求

  • 根據标題查詢
  • 根據标題查詢并且分頁

2.4.2 編寫dao

在dao中添加方法:

public interface ArticleDao extends ElasticsearchRepository<Article, Integer> {

    // 根據标題查詢
    List<Article> findByTitle(String title);

    // 根據标題查詢并且分頁
    Page<Article> findByTitle(String title, Pageable pageable);

}
           

2.4.3 編寫service

  • service接口:在接口中添加方法
// 根據标題查詢
List<Article> findByTitle(String title);

// 根據标題查詢并且分頁
Page<Article> findByTitle(String title, Pageable pageable);
           
  • service實作類:實作接口中方法
// 根據标題查詢
public List<Article> findByTitle(String title) {
    return articleDao.findByTitle(title);
}

// 根據标題查詢并且分頁
public Page<Article> findByTitle(String title, Pageable pageable) {
    return articleDao.findByTitle(title, pageable);
}
           

2.4.4 單元測試

// 根據标題查詢
    @Test
    public void testFindByTitle(){
        Iterable<Article> articles = articleService.findByTitle("版本");
        articles.forEach(article -> System.out.println(article));
    }
    // 根據标題查詢 并分頁
    @Test
    public void testFindByTitleAndPage(){
        Page<Article> page = articleService.findByTitle("es", (PageRequest.of(0, 10)));
        int totalPages = page.getTotalPages();
        long totalElements = page.getTotalElements();
        System.out.println("總頁數:"+totalPages);
        System.out.println("總條數:"+totalElements);

        List<Article> articles = page.getContent();
        articles.forEach(article -> System.out.println(article));
    }
           

3 搭建ES叢集

3.1 叢集搭建

3.1.1 建立目錄

在磁盤的任意盤符下建立es-cluster目錄,并且在該目錄下建立三個檔案夾,分别為node1,node2以及node3,如圖所示:

elasticSearch叢集搭建---入門篇二

3.1.2 複制檔案

将安裝好的es目錄下的相關檔案分别複制到node1\node2\node3目錄下:(删除head插件和曆史資料)

elasticSearch叢集搭建---入門篇二

複制後結果如下:

elasticSearch叢集搭建---入門篇二

3.1.3 修改配置

  • 修改node1節點中的

    node1\config\elasticsearch.yml

    配置檔案,添加如下配置:
    #節點1的配置資訊:
    #叢集名稱,保證唯一
    cluster.name: my-elasticsearch
    #節點名稱,必須不一樣
    node.name: node-1
    #服務端口号,在同一機器下必須不一樣
    http.port: 9200
    #叢集間通信端口号,在同一機器下必須不一樣
    transport.tcp.port: 9300
    #設定叢集自動發現機器ip集合
    discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
               
  • 修改node2節點中的

    node2\config\elasticsearch.yml

    #節點2的配置資訊:
    #叢集名稱,保證唯一
    cluster.name: my-elasticsearch
    #節點名稱,必須不一樣
    node.name: node-2
    #服務端口号,在同一機器下必須不一樣
    http.port: 9201
    #叢集間通信端口号,在同一機器下必須不一樣
    transport.tcp.port: 9301
    #設定叢集自動發現機器ip集合
    discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
               
  • node3\config\elasticsearch.yml

    #節點3的配置資訊:
    #叢集名稱,保證唯一
    cluster.name: my-elasticsearch
    #節點名稱,必須不一樣
    node.name: node-3
    #服務端口号,在同一機器下必須不一樣
    http.port: 9202
    #叢集間通信端口号,在同一機器下必須不一樣
    transport.tcp.port: 9302
    #設定叢集自動發現機器ip集合
    discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
               

3.1.3 啟動服務

依次啟動3台es服務。

elasticSearch叢集搭建---入門篇二
elasticSearch叢集搭建---入門篇二
elasticSearch叢集搭建---入門篇二
elasticSearch叢集搭建---入門篇二
elasticSearch叢集搭建---入門篇二

3.2 測試

3.2.1 通過postman測試

  • 建立索引和映射
# url
PUT     http://localhost:9200/blog1

# 請求體
{
    "mappings": {
		"article": {
			"properties": {
				"id": {
					"type": "long",
					"store": true,
					"index":"not_analyzed"
				},
				"title": {
					"type": "text",
					"store": true,
					"index":"analyzed",
					"analyzer":"standard"
				},
				"content": {
					"type": "text",
					"store": true,
					"index":"analyzed",
					"analyzer":"standard"
				}
			}
		}
	}
}

           
  • 效果
elasticSearch叢集搭建---入門篇二
elasticSearch叢集搭建---入門篇二
  • 添加文檔
# url
POST    localhost:9200/blog1/article/1

# 請求體
{
	"id":1,
	"title":"ElasticSearch是一個基于Lucene的搜尋伺服器",
	"content":"它提供了一個分布式多使用者能力的全文搜尋引擎,基于RESTfulweb接口。Elasticsearch是用Java開發的,并作為Apache許可條款下的開放源碼釋出,是目前流行的企業級搜尋引擎。設計用于雲計算中,能夠時搜尋,穩定,可靠,快速,安裝使用友善。"
}

           
elasticSearch叢集搭建---入門篇二
elasticSearch叢集搭建---入門篇二

3.2.2 通過java代碼測試

package com.demo.test;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
//叢集用戶端下建立索引
public class testCreateMappingByCluster {

    public static void main(String[] args) throws IOException {
        // 1、建立用戶端并且建立連接配接
        Map<String, String> map = new HashMap();
        map.put("cluster.name", "my-elasticsearch");
        InetSocketTransportAddress address1 = new InetSocketTransportAddress(new InetSocketAddress("localhost", 9300));
        InetSocketTransportAddress address2 = new InetSocketTransportAddress(new InetSocketAddress("localhost", 9301));
        InetSocketTransportAddress address3 = new InetSocketTransportAddress(new InetSocketAddress("localhost", 9302));
        Client client = new PreBuiltTransportClient(Settings.builder().put(map).build())
                .addTransportAddresses(address1, address2, address3);
        // 建立映射
        client.admin().indices().prepareCreate("blog2").get();
        // 建立索引
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();
        xContentBuilder
                .startObject()
                    .startObject("properties")
                        .startObject("id")
                            .field("type", "long")
                        .endObject()
                        .startObject("title")
                            .field("type", "text")
                            .field("store", false)
                            .field("analyzer", "ik_smart")
                        .endObject()
                        .startObject("content")
                            .field("type", "text")
                            .field("store", false)
                            .field("analyzer", "ik_smart")
                        .endObject()
                    .endObject()
                .endObject();

        PutMappingRequest mappingRequest = Requests.putMappingRequest("blog2").type("article").source(xContentBuilder);
        client.admin().indices().putMapping(mappingRequest);
        // 3、關閉資源
        client.close();
    }
}

           
elasticSearch叢集搭建---入門篇二
package com.demo.test;

import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.util.HashMap;
// 建立文檔
public class testCreateDoc {
    public static void main(String[] args) throws Exception {
        HashMap<String, Object> map = new HashMap<>();
        map.put("cluster.name","my-elasticsearch");
        Settings settings = Settings.builder().put(map).build();
        //建立用戶端通路對象
        PreBuiltTransportClient client = new PreBuiltTransportClient(settings);
        InetSocketTransportAddress address1 = new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300);
        InetSocketTransportAddress address2 = new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301);
        InetSocketTransportAddress address3 = new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302);
        client.addTransportAddresses(address1,address2,address3);
        // 建立文檔
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                    .field("id", 1)
                    .field("title", "es是什麼")
                    .field("content", "它是基于Lucene的實作的搜尋伺服器")
                .endObject();

        // 添加文檔到指定索引庫
        client.prepareIndex("blog2","article","1").setSource(builder).get();
        client.close();
    }
}

           

3.3 SpringDataElasticsearch配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/data/elasticsearch
      http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
      ">

    <!--包掃描-->
    <context:component-scan base-package="com.demo.service" />

    <!--掃描Dao包,自動建立執行個體,掃描所有繼承ElasticsearchRepository接口的接口-->
    <elasticsearch:repositories base-package="com.demo.dao"/>

    <!--配置elasticSearch的連接配接對象Client-->
    <elasticsearch:transport-client id="client" cluster-nodes="localhost:9301,localhost:9302,localhost:9303" cluster-name="my-elasticsearch"/>

    <!--ElasticSearch模版對象(底層使用模闆操作,需要用spring建立,并注入client)-->
    <bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
        <constructor-arg name="client" ref="client"></constructor-arg>
    </bean>
</beans>
           

繼續閱讀