ES 14 - (Nguyên lý nền tảng) Cách Elasticsearch xử lý nội bộ dữ liệu với các type khác nhau

Mục lục- 1 Chức năng của type

  • 2 Cấu trúc dữ liệu nền tảng của type
  • 3 Khám phá cấu trúc lưu trữ của type
  • 3.1 Tạo index và cấu hình mapping
  • 3.2 Thêm dữ liệu
  • 3.3 Kiểm tra cấu trúc lưu trữ
  • 4 Thực hành tốt nhất với type

1 Chức năng của type

Trong Elasticsearch index, thông qua việc đánh dấu trường meta _type để phân biệt các type khác nhau, do đó chúng ta có thể phân loại các document có cùng trường (field) vào cùng một type.

==> Vì vậy _type còn được gọi là mapping type, tức là mỗi type có mapping riêng của nó.

Nhưng ngay cả khi là dữ liệu tương tự, vẫn có thể có các field khác nhau, ví dụ:

Trong sản phẩm điện tử có trường điện áp; Trong sản phẩm quần áo có trường cách giặt; Trong sản phẩm tươi sống có trường thành phần dinh dưỡng… làm thế nào để xử lý các field khác nhau này?

==> Trong các bài viết trước đã đề cập: Trong các type khác nhau của cùng một index, các field cùng tên phải có cấu hình mapping giống nhau. Tại sao lại như vậy?

2 Cấu trúc dữ liệu nền tảng của type

Trong Lucene - thư viện công cụ cốt lõi mà Elasticsearch sử dụng, không có khái niệm type, khi tạo index, nó xử lý tất cả các giá trị field như kiểu opaque bytes (byte không trong suốt):

Khi lưu document, ES sẽ lưu type mà document đó thuộc về như một trường type;

Khi tìm kiếm document, ES sử dụng _type để lọc và chọn lọc.

Tất cả các type trong một index được lưu trữ cùng nhau, do đó:

Trước Elasticsearch 6.0: Trong các type khác nhau của cùng một index, các field cùng tên phải có cấu hình mapping giống nhau.

Từ Elasticsearch 6.0 trở đi: Một index không thể có nhiều type.

3 Khám phá cấu trúc lưu trữ của type

Lưu ý: Từ Elasticsearch 6.0 trở đi, không cho phép tạo nhiều type trong một index — chỉ có thể tạo một type, nếu không sẽ xảy ra lỗi:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Rejecting mapping update to [products] as the final mapping would have more than 1 type: [electronics, clothing]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "Rejecting mapping update to [products] as the final mapping would have more than 1 type: [electronics, clothing]"
  },
  "status": 400
}

Phiên bản được sử dụng để minh họa là 6.6.0, ghi nhận để tham khảo.

3.1 Tạo index và cấu hình mapping

PUT products
{
    "mappings": {      
        "electronics": {    // Trong phiên bản ES 6.0+, chỉ thêm một type
            "properties": {
                "product_id": { "type": "long" },
                "title": { "type": "text" },
                "price": { "type": "integer" },
                "voltage": { "type": "text", "index": false }
            }
        }
    }
}

3.2 Thêm dữ liệu

PUT products/electronics/1
{
    "product_id": 5001,
    "title": "laptop pro",
    "price": 1500,
    "voltage": "220V"
}

3.3 Kiểm tra cấu trúc lưu trữ

// Tìm kiếm tất cả dữ liệu
GET products/_search

// Kết quả tìm kiếm như sau:
{
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "products",
        "_type" : "electronics",    
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "product_id" : 5001,
          "title" : "laptop pro",
          "price" : 1500,
          "voltage" : "220V"
        }
      }
    ]
  }
}

4 Thực hành tốt nhất với type

Lưu trữ các type có cấu trúc tương tự trong cùng một index — phần lớn các field của các type này nên giống nhau.

Nếu lưu trữ hai type có field hoàn toàn khác nhau trong cùng một index, khi lưu trữ ở tầng Lucene, mỗi document sẽ có phần lớn các field có giá trị rỗng, điều này sẽ gây ra vấn đề nghiêm trọng về hiệu suất và chiếm dụng dung lượng đĩa:

Ví dụ: Trong mỗi document của products/electronics, đều có trường "voltage", chỉ có điều giá trị của chúng đều trống.

—— Từ góc độ này, có thể đoán được lý do ES giới hạn chỉ có thể có một type trong một index là gì rồi, đó là tổ chức dữ liệu tài liệu thuận tiện hơn, tiết kiệm dung lượng đĩa 😊

Đăng vào ngày 16 tháng 6 lúc 07:07