Springboot 整合Elasticsearch

Elasticsearch的安裝和使用

下載Elasticsearch6.2.2的zip包砌溺,并解壓到指定目錄,下載地址:
https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2
安裝中文分詞插件膏秫,在elasticsearch-6.2.2\bin目錄下執(zhí)行以下命令:
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-analysis-ik-6.2.2.zip


運(yùn)行bin目錄下的elasticsearch.bat啟動(dòng)Elasticsearch
下載Kibana,作為訪問(wèn)Elasticsearch的客戶端,請(qǐng)下載6.2.2版本的zip包做盅,并解壓到指定目錄缤削,下載地址:https://artifacts.elastic.co/downloads/kibana/kibana-6.2.2-windows-x86_64.zip
運(yùn)行bin目錄下的kibana.bat,啟動(dòng)Kibana的用戶界面


訪問(wèn)http://localhost:5601 即可打開Kibana的用戶界面

Get Put命令學(xué)習(xí)參考
https://www.xugj520.cn/archives/exploring_cluster.html

Springboot 整合Elasticsearch

版本參考
版本對(duì)應(yīng)很重要 我的是

springboot 2.1.3.RELEASE
es 6.2.2
spring data es 3.1.16.RELEASE

在pom.xml中添加相關(guān)依賴

        <!--Elasticsearch相關(guān)依賴-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.1.16.RELEASE</version>
        </dependency>

修改SpringBoot配置文件

修改application.yml文件吹榴,在spring節(jié)點(diǎn)下添加Elasticsearch相關(guān)配置亭敢。

# elasticsearch相關(guān)配置  .yml全局只能有一個(gè)spring注意
spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch # es集群的名稱
      cluster-nodes: 127.0.0.1:9300 # 程序連接es的端口號(hào)是9300

Model

先寫一個(gè)的商品實(shí)體類,借助這個(gè)實(shí)體類來(lái)完成基礎(chǔ)的CRUD功能

package com.wg.biye.wgcore.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
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;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

//@Accessors @Data 是lombok的注解
//6.0版本以后图筹,一個(gè)index下帅刀,只允許創(chuàng)建一個(gè)type,不允許存在多個(gè)type 并且在官網(wǎng)提供信息远剩,7.0以后不再使用type劝篷。
@Data
@Accessors(chain = true)
@Document(indexName = "wgaituwang", type = "product",shards = 1,replicas = 0)//必須小寫
public class WgProduct implements Serializable {
    /*
    不需要中文分詞的字段設(shè)置成@Field(type = FieldType.Keyword)類型,需要中文分詞的設(shè)置成@Field(analyzer = "ik_max_word",type = FieldType.Text)類型民宿。
    * */
    private static final long serialVersionUID = -1L;

    @Id
    private String id;//必須添加@Id注解,最好為String類型
    @Field(analyzer = "ik_max_word",type = FieldType.Text)//IK分詞器
    private String name;//商品名稱
    private String productAddress;//商品出產(chǎn)地
    private String keywords;//商品關(guān)鍵字
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String title;//商品標(biāo)題
    private Double price;//價(jià)格
//    private String time;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date time;
    /*
    {
    "id" : "1",
    "name" : "火龍果",
    "productAddress" : "北京天安門",
    "keywords" : "水果",
    "title" : "香甜可口的火龍果",
    "price" : "100",
    "time" : "2020-03-27"
    }
    */
}

常用注解學(xué)習(xí)

@Document

屬性名 類型 含義
indexName String 索引庫(kù)名字像鸡,相當(dāng)于mysql中數(shù)據(jù)庫(kù)的概念
type String 文檔類型活鹰,mysql中表的概念
shards short 默認(rèn)分片數(shù) 默認(rèn)值5
replicas short 默認(rèn)副本數(shù)量 默認(rèn)值1

@Id
可以認(rèn)為是mysql中表一行的Id概念
@Field

public @interface Field {
  //文檔中字段的類型
    FieldType type() default FieldType.Auto;
  //是否建立倒排索引
    boolean index() default true;
  //是否進(jìn)行存儲(chǔ)
    boolean store() default false;
  //分詞器名次
    String analyzer() default "";
}

其中字段類型的選項(xiàng)有
//為文檔自動(dòng)指定元數(shù)據(jù)類型
public enum FieldType {
    Text,//會(huì)進(jìn)行分詞并建了索引的字符類型
    Integer,
    Long,
    Date,
    Float,
    Double,
    Boolean,
    Object,
    Auto,//自動(dòng)判斷字段類型
    Nested,//嵌套對(duì)象類型
    Ip,
    Attachment,
    Keyword//不會(huì)進(jìn)行分詞建立索引的類型
}

創(chuàng)建repository包


創(chuàng)建實(shí)體類的接口繼承ElasticsearchRepository這樣就有基本的CRUD(用過(guò)Jpa的就很清楚)

package com.wg.biye.wgcore.repository;

import com.wg.biye.wgcore.entity.WgProduct;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import org.springframework.stereotype.Repository;

@Repository
public interface WgProductRepository extends ElasticsearchRepository<WgProduct, String> {
}

我們就直接實(shí)現(xiàn)控制類吧

package com.wg.biye.wgcore.controller;

import com.wg.biye.common.util.ResultUtil;
import com.wg.biye.wgcore.entity.WgProduct;
import com.wg.biye.wgcore.repository.WgProductRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
//需要一個(gè)工具將MySQL的數(shù)據(jù)導(dǎo)入Elasticsearch
//@RestController = @Controller + @ResponseBody組成
@RestController
@RequestMapping("/wgproduct")
public class WgProductController {
    @Autowired
    private WgProductRepository wgProductRepository;

    //@RequestBody學(xué)習(xí) : https://blog.csdn.net/justry_deng/article/details/80972817
    @PostMapping("/add")
    public Map<String, Object> add(@RequestBody WgProduct wgProduct) {
        System.out.println(wgProduct.toString());
        System.out.println(wgProduct instanceof  WgProduct);//true
        wgProductRepository.save(wgProduct);
        return ResultUtil.resultCode(200,"添加商品成功"); ResultUtil工具換成自己的就行
    }
    //根據(jù)Id查詢
    @GetMapping("/get/{id}")
    public Map<String, Object> getById(@PathVariable String id) {
        Map<String,Object> result = new HashMap<>();
        if (StringUtils.isEmpty(id))
            return ResultUtil.resultCode(500,"Id為空");
        //【java8新特性】Optional詳解 http://www.reibang.com/p/d81a5f7c9c4e
        Optional<WgProduct> wgProductOptional = wgProductRepository.findById(id);
        if (wgProductOptional.isPresent()) {//isPresent()方法用于判斷包裝對(duì)象的值是否非空
            WgProduct wgProduct = wgProductOptional.get();
            result.put("商品信息",wgProduct);
            return ResultUtil.resultSuccess(result);
        }
        return ResultUtil.resultError(result);
    }
    //查詢所有
    @GetMapping("/getall")
    public Map<String, Object> getAll() {
        Map<String,Object> result = new HashMap<>();
        Iterable<WgProduct> iterable = wgProductRepository.findAll();
        List<WgProduct> list = new ArrayList<>();
        iterable.forEach(list::add);
        result.put("所有商品",list);
        return ResultUtil.resultSuccess(result);
    }
//    根據(jù)ID修改
    @PostMapping("/update")
    public Map<String, Object> updateById(@RequestBody WgProduct wgProduct) {
        String id = wgProduct.getId();
        if (StringUtils.isEmpty(id))
            return ResultUtil.resultCode(500,"Id為空");
        wgProductRepository.save(wgProduct);
        return ResultUtil.resultCode(200,"修改商品成功");
    }
//    根據(jù)ID刪除
    @DeleteMapping("/delete/{id}")
    public Map<String, Object> deleteById(@PathVariable String id) {
        if (StringUtils.isEmpty(id))
            return ResultUtil.resultCode(500,"Id為空");
        wgProductRepository.deleteById(id);
        return ResultUtil.resultCode(200,"刪除商品成功");
    }
}

POSTMAN測(cè)試

增加


查看

刪除

搜索

構(gòu)造數(shù)據(jù) 在測(cè)試類胡亂寫

package com.wg.biye;

import com.wg.biye.wgcore.entity.*;
import com.wg.biye.wgcore.repository.WgProductRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;


@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class BiyeApplicationTests {

    @Autowired
    private WgProductRepository wgProductRepository;

    @Test
    public void contextLoads() {
        WgProduct wgProduct = new WgProduct();
        wgProduct.setId("100");
        wgProduct.setTitle("好吃的");
        wgProduct.setProductAddress("北京");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("水果");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);

        wgProduct.setId("101");
        wgProduct.setTitle("好玩的");
        wgProduct.setProductAddress("成都");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("水果");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);

        wgProduct.setId("102");
        wgProduct.setTitle("好喝的");
        wgProduct.setProductAddress("成都");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("飲料");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);

        wgProduct.setId("103");
        wgProduct.setTitle("好玩的");
        wgProduct.setProductAddress("北京");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("玩具");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);

        wgProduct.setId("104");
        wgProduct.setTitle("好吃的");
        wgProduct.setProductAddress("北京");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("水果");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);

        wgProduct.setId("105");
        wgProduct.setTitle("好吃的");
        wgProduct.setProductAddress("成都");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("水果");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);

        wgProduct.setId("106");
        wgProduct.setTitle("好吃的");
        wgProduct.setProductAddress("北京");
        wgProduct.setPrice(20.0);
        wgProduct.setTime(new Date());
        wgProduct.setKeywords("水果");
        wgProduct.setName("梨");
        wgProductRepository.save(wgProduct);
    }
}

查詢所有數(shù)據(jù)

搜索標(biāo)題中以關(guān)鍵字開頭的方法

WgProductRepository.class添加方法
List<WgProduct> findAllByTitleLike(String s);

控制器添加

    @GetMapping("/search/title")
    public Map<String, Object> repSearchTitle(String keyword) {
        if (StringUtils.isEmpty(keyword))
            return ResultUtil.resultCode(500,"條件為空");
        Map<String,Object> result = new HashMap<>();
        List<WgProduct> list = new ArrayList<>();
        list = wgProductRepository.findAByTitleLike(keyword);
        result.put("搜索結(jié)果",list);
        return ResultUtil.resultSuccess(result);
    }

搜索結(jié)果

{
    "code": 200,
    "搜索結(jié)果": [
        {
            "id": "100",
            "name": "梨",
            "productAddress": "北京",
            "keywords": "水果",
            "title": "好吃的",
            "price": 20.0,
            "time": "2020-03-27"
        },
        {
            "id": "104",
            "name": "梨",
            "productAddress": "北京",
            "keywords": "水果",
            "title": "好吃的",
            "price": 20.0,
            "time": "2020-03-27"
        },
        {
            "id": "105",
            "name": "梨",
            "productAddress": "成都",
            "keywords": "水果",
            "title": "好吃的",
            "price": 20.0,
            "time": "2020-03-27"
        },
        {
            "id": "106",
            "name": "梨",
            "productAddress": "北京",
            "keywords": "水果",
            "title": "好吃的",
            "price": 20.0,
            "time": "2020-03-27"
        }
    ],
    "message": "操作成功"
}

更多API請(qǐng)參考

https://docs.spring.io/spring-data/elasticsearch/docs/3.1.16.RELEASE/reference/html/#populator.namespace-dao-config

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市只估,隨后出現(xiàn)的幾起案子志群,更是在濱河造成了極大的恐慌,老刑警劉巖蛔钙,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锌云,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡吁脱,警方通過(guò)查閱死者的電腦和手機(jī)桑涎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)兼贡,“玉大人攻冷,你說(shuō)我怎么就攤上這事”橄#” “怎么了等曼?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我禁谦,道長(zhǎng)胁黑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任州泊,我火速辦了婚禮丧蘸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拥诡。我一直安慰自己触趴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布渴肉。 她就那樣靜靜地躺著冗懦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仇祭。 梳的紋絲不亂的頭發(fā)上披蕉,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音乌奇,去河邊找鬼没讲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛礁苗,可吹牛的內(nèi)容都是我干的爬凑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼试伙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嘁信!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起疏叨,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤潘靖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蚤蔓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卦溢,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年秀又,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了单寂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吐辙,死狀恐怖凄贩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袱讹,我是刑警寧澤疲扎,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布昵时,位于F島的核電站,受9級(jí)特大地震影響椒丧,放射性物質(zhì)發(fā)生泄漏壹甥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一壶熏、第九天 我趴在偏房一處隱蔽的房頂上張望句柠。 院中可真熱鬧,春花似錦棒假、人聲如沸溯职。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谜酒。三九已至,卻和暖如春妻枕,著一層夾襖步出監(jiān)牢的瞬間僻族,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工屡谐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留述么,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓愕掏,卻偏偏與公主長(zhǎng)得像度秘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饵撑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容