+4

Tạo một project với Spring Boot và Elasticsearch 8.4.1 sử dụng thư viện Spring data elasticsearch. Hướng dẫn cài đặt và sự khác nhau giữa 2 phiên bản 8.x.x với 7.x.x Elasticsearch

Trong bài viết này, tôi sẽ hướng dẫn các bạn 2 phần:

  • Cấu hình Elasticsearch

  • Tạo project với spring boot sử dụng thư viện spring data elasticsearch

Công cụ và thư viện được sử dụng trong bài viết:

  • Spring tool suite 4
  • Spring boot 2.7.3
  • Spring data elasticsearch 4.4.2
  • Maven 3
  • Java 8
  • Elasticsearh 8.4.1
  • Elasticsearch 7.17.6
  • Postman
  • Elasticsearch head extension

1. Cài đặt Elasticsearch:

Đầu tiên các bạn truy cập đường dẫn bên dưới để tải về Elasticsearch mới nhất:

Link: https://www.elastic.co/downloads/elasticsearch

Nếu muốn tải về Elasticsearch phiên bản thấp hơn thì truy cập link bên dưới:

Link: https://www.elastic.co/downloads/past-releases

Trong bài viết này tôi tải về Elasticsearch zip file. Sau khi tải về tiến hành giải nén ta được thư mục như hình:

image.png

Cấu trúc thư mục:

image.png

Vào folder "config" và mở file "elasticsearch.yml":

image.png

Nội dung config file:

image.png

Thực sự không cần chỉnh sửa giá trị nào trong config file nhưng có 2 giá trị chúng ta cần quan tâm

  • cluster.name -> thiếp lập tên cho cluster. Tại đây tôi sẽ delete ký tự "#" và sửa tên thành "employee-cluster"

  • path.data -> thiếp lập đường dẫn lưu data. Tại đây tôi sẽ thiết lập lại đường dẫn thành "G:/elasticsearch-8.4.1/data"

image.png

Mặc định trong thư mục Elasticsearch vừa giải nén sẽ không có folder "data" nên tôi sẽ tự tạo 1 folder name là "data":

image.png

Tiếp theo để khởi động elasticsearch, tôi mở folder name là "bin" và run script file "elasticsearch.bat":

image.png

image.png

Sau khi khởi chạy thành công, truy cập đường dẫn "localhost:9200" để kiểm tra xem trạng thái Elasticsearch:

image.png

Như các bạn thấy, elasticsearch vẫn chưa hoạt động, check màn hình cmd thấy một vài lỗi về kết nối:

image.png

Lỗi này xảy ra trên phiên bản Elasticsearch 8 và để xử lý lỗi này, tôi sẽ mở file "elasticsearch.yml" trong folder "config" để sửa một vài thông tin:

image.png

Có 4 giá trị cần phải thay đổi, mặc định là "true" nên tôi sẽ chuyển thành "false":

  • xpack.security.enabled: true -> xpack.security.enabled: false

  • xpack.security.enrollment.enabled: true -> xpack.security.enrollment.enabled: false

  • xpack.security.http.ssl: enabled: true => xpack.security.http.ssl: enabled: false

  • xpack.security.transport.ssl: enabled: true => xpack.security.transport.ssl: enabled: false

image.png

Sau khi cập nhật lại 4 giá trị, vào folder "../bin" và khởi chạy script file "elasticsearch.bat":

Sau khi khởi chạy thành công, tiếp tục thử lại truy cập đường dẫn "localhost:9200":

image.png

Ta thấy elasticsearch đã khởi chạy thành công

Tiếp theo tôi giới thiệu các bạn 1 extension trên chrome hỗ trợ việc kiểm tra data trên elasticsearch gọi là "elasticsearch head":

Link: https://chrome.google.com/webstore/detail/multi-elasticsearch-head/cpmmilfkofbeimbmgiclohpodggeheim

Sau khi cài đặt extension ở trên thành công, click icon extension:

image.png

Chọn "Multi Elasticsearch Head" và đây là giao diện:

image.png

Các bạn click chọn tab "Structured Query" sẽ thấy hiện chưa có bất kỳ document nào:

image.png

Vậy là cơ bản đã xong phần cài đặt và cấu hình Elasticsearch. Tiếp theo tôi sẽ tạo một project với Spring boot và Spring data elasticsearch.

2. Cấu trúc thư mục:

image.png

3. Nội dung file pom:

image.png

4. Tạo class "Employee" trong package "com.example.elasticsearch.model":

image.png

Trong class "Employee" có 2 annotation, tôi sẽ phân tích từng cái:

  • @Document: Nếu các bạn đã từng làm việc với Hibernate thì sẽ biết "@Table" -> "@Document" cũng tương tự như "@Table", nó sẽ thực hiện ánh xạ class "Employee" này với index name là "employee"

  • @Id: Annotation dùng để đánh dấu cho biết giá trị biến "id" này là khoá chính

Và có 1 lưu ý, với phiên bản Elasticsearch 8.x.x thì đã bỏ thuộc tính "type". Các bạn có thể tham khảo thông tin này trang chủ elastic:

image.png

Link: https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html

Tiếp tục, khi tạo xong class "Employee", tôi tiến hành start project và lên giao diện "Elasticsearch head" để kiểm tra xem "document" đã được tạo chưa:

image.png

Click vào icon được khoanh đỏ để reset lại trạng thái:

image.png

Sau khi reset thành công sẽ thấy từ "Green" chuyển thành "Yellow" và đã có "document" với index name là "employee"

Tôi click chọn tab "Structured Query" thấy "document" với index name là "employee" được tạo nhưng hiện tại chưa có data nào:

image.png

5. Tạo 1 interface "EmployeeRepository" trong package "com.example.elasticsearch.repository":

image.png

Trong interface "EmployeeRepository" tôi cho kế thừa "ElasticsearchRepository" và khai báo 1 method "findByName", thực sự mặc định "ElasticsearchRepository" đã hỗ trợ 1 số method như "findAll()"; "findById()";"findByName()";...

Cần khai báo package chứa những repository trong class khởi động "ElasticSearchApplication", dùng annotation "@EnableElasticsearchRepositories":

image.png

6. Tạo 1 class "EmployeeController" trong package "com.example.elasticsearch.controller":

image.png

Trong class controller tôi cần sử dụng những method "findAll()"; "findById()";"findByName()" được hỗ trợ bởi "ElasticsearchRepository", vì vậy tôi sẽ dùng annotation "@AutoWired" để khai báo "EmployeeRepository"

Tôi tiến hành test với Postman:

  • Call api tạo mới employee với data body là 1 list:

      [
      {
          "id":"11",
          "name":"A",
          "title":"SE",
          "age": 31
      },
      {
          "id":"12",
          "name":"C",
          "title":"BA",
          "age": 22
      }]
    

image.png

Kết quả test:

image.png

Kiểm tra lỗi:

image.png

image.png

Đầu tiên, tôi sẽ lên Elasticsearch head và kiểm tra xem dữ liệu đã được thêm mới thành công hay chưa:

image.png

Các bạn có thể thấy index name "employee" hiện đang có 2 docs -> dữ liệu đã được thêm thành công và tại mục "Results:" đang để mặc định là "Table" tôi sẽ chọn lại thành "JSON" và click "Search" để thấy tất cả dữ liệu đang có:

image.png

Kết quả cho thấy dữ liệu được tạo thành công, vậy tại sao lại báo lỗi? thực sự lỗi này gặp ở phiên bản Elasticsearch 8.x.x bởi vì tôi có nói ở đầu bài viết là với phiên bản Elasticsearch 8.x.x thì thuộc tính "type" đã bị xoá và chỉ có những phiên bản cũ hơn mới có thuộc tính "type"

Đây là nguyên nhân văng ra lỗi, các bạn thấy lỗi tôi khoanh đỏ ở trên tại class "DocWriteResponse", trong class này tại constructor khi gán giá trị cho thuộc tính "type" nó yêu cầu thuộc tính "type" không được null:

image.png

Và vì thế khi thấy "type" null -> văng lỗi

Thực sự dữ liệu đã được thêm thành công nhưng làm thế nào để không văng lỗi, tôi có 2 giải pháp:

  • Giải pháp thứ 1(khuyên dùng): Tại về phiên bản elasticsearch 7.x.x trở về trước -> sẽ không có lỗi xảy ra

  • Giải pháp thứ 2: Bọc "try{}catch()".

Tôi sẽ thử cả 2 giải pháp ở trên:

  • Giải pháp thứ 2:

image.png

Kết quả khi call api tạo mới employee:

image.png

Kết quả khi call api delete employee by id:

image.png

image.png

Kết quả khi call api cập nhật thông tin employee by id:

image.png

image.png

Kết quả khi trích xuất thông tin employee by id:

image.png

=> Dữ liệu được xử lý thành công nhưng giải pháp này không hiệu quả bởi vì có thể sẽ bị bỏ qua những lỗi khác và nếu bạn muốn khoanh vùng những lỗi nào cho qua hoặc không thì cần phải lấy ra tên lỗi và loại trừ ra. Có thể dùng "{exeption}.getClass().getSimpleName()" để lấy ra tên lỗi

Tôi sẽ dùng giải pháp thứ 1, dùng phiên bản Elasticsearch cũ hơn, ở đây tôi dùng phiên bản 7.17.6(phiên bản cuối cùng của 7.x.x). Cấu hình cũng tương tự như tôi đã giải thích ở đầu bài viết

Kiểm tra thông tin phiên bản:

image.png

Kiểm tra Elasticsearch head:

image.png

Chưa có document nào

Start project:

Kiểm tra lại Elasticsearch head:

image.png

image.png

Chưa có bất kỳ data nào

Cập nhật lại "EmployeeControler", bỏ "try{}catch()":

image.png

Tiến hành test:

Kết quả khi call api tạo mới employee:

image.png

image.png

Kết quả khi call api delete employee by id:

image.png

image.png

Kết quả khi call api cập nhật thông tin employee by id:

image.png

image.png

Kết quả khi trích xuất thông tin employee by id:

image.png

=> Các bạn thấy với phiên bản Elasticsearch 7.x.x vẫn có thuộc tính "type" và quá trình call api không có bất kỳ lỗi nào xảy ra

Download source: http://megaurl.in/Aw60j

Bài viết khá dài nên tôi sẽ dừng tại đây và trong bài viết sau tôi sẽ tạo 1 project Spring boot với thymeleaf và spring data elasticsearch.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí