SpringBoot集成Elasticsearch

一.ES簡介

elasticsearch是一個高度可擴展的開源全文搜索和分析引擎,能夠快速的、近實時地對大數據進行存儲、搜索和分析,用來支撐複雜的數據搜索需求和企業級應用,主要用於海量系統日誌的數據查詢與分析。
java

二.ES安裝

  1. 下載地址:https://www.elastic.co/downloads/elasticsearch
  2. 下載ES壓縮包解壓後,進入bin目錄,雙擊elasticsearch.bat便可啓動es
  3. 啓動es服務後,訪問localhost:9200,瀏覽器出現以下信息說明啓動成功.
{
  "name" : "YNFljfo",
  "cluster_name" : "my-application",
  "cluster_uuid" : "iuLpWK05SJGSqp5evk7Gpg",
  "version" : {
    "number" : "6.2.4",
    "build_hash" : "ccec39f",
    "build_date" : "2018-04-12T20:37:28.497551Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

三.head插件的安裝

head插件能夠很方便的操做es,head插件與es的關係就像navicat與MySQL數據庫的關係,不過head插件的界面是經過訪問網址瀏覽的。node

  1. 下載head插件:https://github.com/search?q=elasticsearch-head
  2. 由於head插件依賴node環境,因此須要安裝node.js:https://nodejs.org/en/download/
  3. 運行head須要藉助grunt命令,因此要安裝。
    在cmd窗口進入node.js安裝的根目錄,而後執行npm install -g grunt -cli
  4. 安裝pathomjs:
    在cmd命令窗口進入head插件解壓後的根目錄,而後執行npm install
  5. 鏈接es: 設置跨域訪問,在es的安裝根目錄的config目錄下有elasticsearch.yml,在此文件中添加以下內容:
http.cors.enabled: true
http.cors.allow-origin: "*"

將cluster.name: my-application的註釋取消
  1. 運行head:
    在cmd命令窗口進入head插件解壓後的根目錄,而後執行grunt server,以下圖就啓動成功。

1568256015(1).png.png&originHeight=114&originWidth=472&size=5531&status=done&width=472)git

  1. 而後訪問localhost:9100看到以下畫面就安裝成功

1568256194(1).png.png&originHeight=349&originWidth=990&size=28420&status=done&width=990)
github

四.Springboot集成ES

  1. 添加依賴及配置application.properties文件
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
 </dependency>
spring.data.elasticsearch.cluster-name=my-application
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
  1. 建立實體類及響應體
@Data
@Document(indexName = "person")
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable {
    @Id
    private String skuId;
    private String name;
    private String address;
    private Integer age;
    private String sex;
    private String city;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Response {

    private Integer code;
    private String message;
    private Object data;


    public static Response successMsg(){
        Response response=new Response();
        response.setCode(200);
        response.setMessage("請求成功");
        return response;
    }

    public static Response failed404(){
        Response response=new Response();
        response.setCode(404);
        response.setMessage("請求失敗");
        return response;
    }
}
  1. 建立es的Service

    自定義接口實現ElasticsearchRepository,相似於與數據庫交互的dao層,提供了對es的基本操做。spring

public interface  PersonRepository extends ElasticsearchRepository<Person,String> {


}

@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();
}
public interface PersonService {

    long count();

    Person save(Person person);

    void delete(Person person);

    Iterable<Person> getAll();

    List<Person> getByName(String name);

    Page<Person> pageQuery(Integer pageNo, Integer pageSize, String kw);
}
@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonRepository personRepository;

    @Override
    public long count() {
        return personRepository.count();
    }

    @Override
    public Person save(Person person) {
        return personRepository.save(person);
    }

    @Override
    public void delete(Person person) {
        personRepository.delete(person);
    }

    @Override
    public Iterable<Person> getAll() {
        return personRepository.findAll();
    }

    @Override
    public List<Person> getByName(String name) {
        List<Person> personList=new ArrayList<>();
        MatchQueryBuilder queryBuilder=new MatchQueryBuilder("name",name);
        Iterable<Person> personIterable=personRepository.search(queryBuilder);
        personIterable.forEach(personList::add);
        return personList;
    }

    @Override
    public Page<Person> pageQuery(Integer pageNo, Integer pageSize, String kw) {
        SearchQuery searchQuery=new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhraseQuery("name",kw)).withPageable(PageRequest.of(pageNo,pageSize)).build();
        return personRepository.search(searchQuery);
    }
}
  1. Junit測試

Springboot提供了ElasticsearchTemplate,也可實現的ES的數據操做。數據庫

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringEsApplicationTests {


    @Autowired
    public PersonService personService;

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;
    @Test
    public void contextLoads() {
        Person person=new Person("123456","zlc","西湖區",18,"男","hangzhou");
        personService.save(person);
        Person person1=new Person("98712","張三","餘杭區",18,"男","hangzhou");
        IndexQuery indexQuery=new IndexQueryBuilder().withObject(person1).build();
        elasticsearchTemplate.index(indexQuery);

    }

}
  1. 建立controller
@RestController
@RequestMapping("/es")
public class EsController {


    @Autowired
    PersonService personService;


    /**
     * 向es添加數據
     */
    @RequestMapping("/insert")
    public Object insert(@RequestBody Person person){
        JSONObject object=null;
        try {
          Person savePerson=  personService.save(person);
          object= (JSONObject) JSON.toJSON(savePerson);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return object;
    }


    /**
     * 從es刪除數據
     * @param person
     * @return
     */
    @RequestMapping("/delete")
    public Object delete(@RequestBody Person person){

        try {
            personService.delete(person);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.failed404();
        }
        return Response.successMsg();

    }


    /**
     * 查詢操做
     * @param pageNo
     * @param pageSize
     * @param key
     * @return
     */
    @RequestMapping("/query")
    public Object query(@RequestParam(value = "pageNo",required = false)Integer pageNo,@RequestParam(value = "pageSize",required = false)Integer pageSize,
    @RequestParam(value = "key",required = false)String key){

        Response response=new Response();
        try {
            Page<Person> personPage= personService.pageQuery(pageNo,pageSize,key);
            response.setData(personPage);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.failed404();
        }
        return response;

    }
}

經過Postman測試查詢結果以下:
1568258391(1).png.png&originHeight=858&originWidth=1098&size=38028&status=done&width=1098)
npm

五.錯誤解決

  1. SpringBoot加載elasticsearch節點失敗
failed to load elasticsearch nodes : org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available:

初步斷定,應該是spring-boot-starter-data-elasticsearch與Elasticsearch 7.x版本不兼容形成的。
經過測試發現,將Elasticsearch降級到6.x版本,便可解決。
2.修改elasticsearch.yml後雙擊elasticsearch.bat閃退
緣由是elasticsearch.yml默認是utf-8編碼,因此添加的屬性保存時也得是utf-8編碼的。json

六.源碼下載地址

https://github.com/liankaizha...跨域


參考文獻:瀏覽器

1.https://cloud.tencent.com/developer/article/1461537

相關文章
相關標籤/搜索