0

Elasticsearch Bài học 5: Cơ chế CRUD cơ bản - Thêm, Đọc, Sửa, Xóa Document đầu tiên

Bạn đã hiểu tư duy thiết kế phi chuẩn hóa (Bài 4) và đang mở sẵn Kibana Dev Tools (Bài 3). Bây giờ là lúc chúng ta thực sự "chạm" vào dữ liệu.

Trong Elasticsearch, các thao tác CRUD (Create - Read - Update - Delete) được thực hiện thông qua các HTTP Method chuẩn mực (POST, GET, PUT, DELETE). Mọi bản ghi dữ liệu (Document) đều được đặt trong một không gian lưu trữ gọi là Index.

Hãy mở Kibana Dev Tools và cùng thực hiện vòng đời của một Document mang tên "Sữa rửa mặt".

1. Create - Thêm dữ liệu (Indexing)

Quá trình thêm một Document vào Elasticsearch được gọi là Indexing (đánh chỉ mục). Có hai cách để thêm dữ liệu: Tự định nghĩa ID hoặc để Elasticsearch tự sinh ID.

Cách 1: Tự định nghĩa ID (Dùng PUT)

Thường dùng khi bạn đồng bộ dữ liệu từ MySQL/PostgreSQL sang Elasticsearch và muốn giữ nguyên Primary Key làm ID gốc. Cú pháp: PUT /{index_name}/_doc/{id}

Chạy lệnh sau trong Dev Tools:

JSON

PUT products/_doc/1
{
  "name": "Sữa rửa mặt Cetaphil 500ml",
  "price": 250000,
  "category": "Chăm sóc da",
  "stock": 150,
  "tags": ["dịu nhẹ", "da mụn"]
}

Kết quả trả về: Bạn sẽ thấy trường "result": "created". Elasticsearch đã tự động tạo luôn Index products (vì nó chưa tồn tại) và insert Document có ID = 1.

Cách 2: Để Elasticsearch tự sinh ID (Dùng POST)

Nếu hệ thống của bạn là nơi sinh ra dữ liệu gốc (ví dụ: hệ thống ghi Log), bạn không cần bận tâm đến ID. Cú pháp: POST /{index_name}/_doc

JSON

POST products/_doc
{
  "name": "Nước tẩy trang Bioderma",
  "price": 300000,
  "category": "Chăm sóc da",
  "stock": 80
}

Kết quả trả về: Elasticsearch sẽ tự động gán một chuỗi random 20 ký tự (ví dụ: "_id": "Kj8XjYsB9a...") siêu nhanh và đảm bảo không đụng độ (collision-free).

2. Read - Đọc dữ liệu (Get API)

Để lấy một Document cụ thể khi đã biết chính xác ID, chúng ta dùng phương thức GET. (Lưu ý: Đây là thao tác lấy trực tiếp bằng ID, không phải là "Tìm kiếm - Search" toàn văn bản).

Lấy toàn bộ thông tin Document

JSON

GET products/_doc/1

Kết quả trả về sẽ có cấu trúc như sau:

JSON

{
  "_index": "products",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "name": "Sữa rửa mặt Cetaphil 500ml",
    "price": 250000,
    "category": "Chăm sóc da",
    "stock": 150,
    "tags": [ "dịu nhẹ", "da mụn" ]
  }
}

Điểm cốt lõi: Toàn bộ cục JSON bạn gửi lên lúc nãy được Elasticsearch đóng gói gọn gàng bên trong block _source. Các trường có dấu _ đứng trước (như _index, _id, _version) là metadata do hệ thống quản lý.

Chỉ lấy dữ liệu _source (Lọc metadata)

Nếu hệ thống API Backend của bạn chỉ muốn nhận payload gốc mà không cần metadata thừa thãi, hãy dùng endpoint _source:

JSON

GET products/_source/1

3. Update - Cập nhật dữ liệu

Elasticsearch có một đặc tính thú vị: Các Document là Bất biến (Immutable). Bạn không thể chọc trực tiếp vào ổ cứng để sửa vài byte dữ liệu. Mọi thao tác "Update" thực chất là Elasticsearch đánh dấu Document cũ là "đã xóa" (tombstone) và tạo ra một Document hoàn toàn mới.

Cách 1: Ghi đè toàn bộ (Full Update bằng PUT)

Nếu bạn chạy lại lệnh PUT với cùng ID, Elasticsearch sẽ ghi đè toàn bộ.

JSON

PUT products/_doc/1
{
  "name": "Sữa rửa mặt Cetaphil 500ml",
  "price": 270000 
}

(Cảnh báo: Nếu bạn làm thế này, các trường cũ như category, stock, tags sẽ bị mất sạch vì JSON mới đã ghi đè JSON cũ. _version sẽ tăng từ 1 lên 2).

Cách 2: Cập nhật một phần (Partial Update bằng POST _update)

Đây là cách an toàn và tối ưu băng thông mạng nhất. Bạn chỉ gửi lên trường cần thay đổi, Elasticsearch sẽ tự lấy nội dung cũ, gộp với nội dung mới và ghi lại xuống đĩa. Cú pháp: POST /{index_name}/_update/{id}

JSON

POST products/_update/1
{
  "doc": {
    "price": 210000,
    "stock": 140
  }
}

Lưu ý quan trọng: Phải bọc các trường cần sửa bên trong object "doc": {}.

4. Delete - Xóa dữ liệu

Xóa một Document rất đơn giản bằng phương thức DELETE:

JSON

DELETE products/_doc/1

Kết quả trả về "result": "deleted".

Nếu bạn kiểm tra lại bằng lệnh GET products/_doc/1, bạn sẽ nhận được "found": false.

Bí mật vận hành: Khi bạn gọi DELETE, dữ liệu không bị xóa khỏi ổ đĩa ngay lập tức. Elasticsearch chỉ đánh dấu (mark as deleted) để bỏ qua nó trong các lượt tìm kiếm. Dữ liệu thực sự sẽ bị dọn dẹp ở dưới background trong quá trình "Merge Segments" (chúng ta sẽ tìm hiểu cơ chế này ở Bài 9).


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í