0

Giải phẫu Elasticsearch Query DSL dạng Array: "Bộ não" tổng hợp logic của công cụ tìm kiếm

Khi làm việc với các hệ thống backend có lượng dữ liệu lớn và yêu cầu tìm kiếm phức tạp (như tìm kiếm sản phẩm theo từ khóa, lọc theo danh mục, khoảng giá, và trạng thái còn hàng cùng lúc), SQL đôi khi sẽ trở nên chậm chạp hoặc khó viết. Đó là lúc chúng ta phải nhờ đến Elasticsearch và ngôn ngữ truy vấn độc quyền của nó: Query DSL (Domain Specific Language).

Điểm đặc trưng nhất, đồng thời cũng là thứ khiến nhiều lập trình viên mới làm quen cảm thấy "lú" nhất khi nhìn vào Elasticsearch chính là cấu trúc Array (Mảng) được lồng nhau liên tục. Hôm nay, chúng ta hãy cùng mổ xẻ kiến trúc Query DSL dạng Array này để hiểu tại sao nó lại được thiết kế như vậy nhé!

1. Query DSL dạng Array thực chất là gì?

Query DSL của Elasticsearch được xây dựng hoàn toàn dựa trên định dạng JSON. Khác với SQL viết theo kiểu tuyến tính (SELECT * FROM users WHERE age > 18 AND status = 'active'), Elasticsearch sử dụng các Block (Khối) và Mảng (Array) để nhóm các điều kiện lại với nhau.

Cấu trúc cốt lõi của một truy vấn dạng mảng thường xoay quanh các toán tử logic (Bool Query) như must, should, filter, và must_not. Tất cả các điều kiện con bên trong các toán tử này đều phải được đặt bên trong một mảng ([...]).

Ví dụ một cấu trúc Query DSL kinh điển:

{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "laptop gaming" } }
      ],
      "filter": [
        { "term": { "status": "active" } },
        { "range": { "price": { "gte": 10000000, "lte": 30000000 } } }
      ]
    }
  }
}

Nhìn vào đoạn JSON trên, bạn có thể thấy các mảng [...] đóng vai trò là "chiếc giỏ" chứa đựng nhiều điều kiện tìm kiếm độc lập bên trong.

2. "Bộ tứ quyền lực" bên trong mảng Bool Query

Để làm chủ cấu trúc Array này, bạn chỉ cần nắm vững 4 từ khóa cốt lõi đại diện cho các điều kiện logic:

  • must (Phải thỏa mãn - AND): Các điều kiện nằm trong mảng must bắt buộc phải khớp. Đồng thời, chúng sẽ tham gia vào việc tính điểm liên quan (Relevance Score) để sắp xếp kết quả từ cao xuống thấp. (Giống như phép AND kèm chấm điểm).
  • filter (Lọc dữ liệu - AND nhưng không tính điểm): Giống như must, các điều kiện trong mảng filter cũng bắt buộc phải đúng. Tuy nhiên, nó không tính điểm score. Việc này giúp Elasticsearch có cơ hội tối ưu hóa bộ nhớ đệm (Query Cache), khiến tốc độ truy vấn nhanh hơn đáng kể. Rất thích hợp cho việc lọc giá, lọc ngày tháng, lọc trạng thái.
  • should (Nên thỏa mãn - OR): Các điều kiện nằm trong mảng should hoạt động như phép OR. Nếu document khớp với một hoặc nhiều điều kiện trong này thì càng tốt, điểm số sẽ tăng lên. (Trừ khi được ép buộc bằng tham số minimum_should_match).
  • must_not (Tuyệt đối không - NOT): Loại bỏ hoàn toàn các document thỏa mãn điều kiện bên trong mảng này.

3. Tại sao Elasticsearch lại thiết kế dạng Array thay vì phẳng hóa?

Nhiều lập trình viên chuyển từ SQL sang thường thắc mắc: "Tại sao phải bọc trong mảng nhiều tầng ngoặc nhọn nhìn rối mắt thế, sao không viết phẳng ra?". Thiết kế này thực ra mang lại những ưu điểm cực kỳ lớn:

  • Khả năng mở rộng vô hạn (Extensibility): Bằng việc sử dụng mảng ([]), một tiêu chí tìm kiếm có thể chứa từ 1 cho đến hàng ngàn điều kiện con mà không làm thay đổi cấu trúc cốt lõi của câu lệnh. Bạn muốn thêm 5 điều kiện lọc giá nữa? Chỉ việc nhét thêm phần tử vào trong mảng filter, câu lệnh không bao giờ bị vỡ cấu trúc cú pháp.
  • Dễ dàng sinh mã tự động (Programmatic Generation): Từ góc độ của backend code (PHP, Node.js, Go...), việc xây dựng một câu query động bằng mảng JSON cực kỳ dễ dàng. Bạn chỉ cần dùng vòng lặp foreach để push các điều kiện lọc vào một mảng tạm rồi truyền thẳng vào payload của Elasticsearch mà không phải lo lỗi nối chuỗi (String Concatenation) hay dính lỗi SQL Injection.
  • Tách bạch giữa tìm kiếm toàn văn và lọc chính xác: Kiến trúc mảng của bool query phân định rõ ràng ranh giới giữa việc "Tìm kiếm theo độ mờ / từ khóa" (must) và "Lọc dữ liệu chính xác tuyệt đối" (filter), giúp công cụ tìm kiếm tối ưu hóa hiệu năng phần cứng một cách tối đa.

Lời kết

Cấu trúc Query DSL dạng Array trong Elasticsearch thoạt nhìn có vẻ rườm rà với những cặp ngoặc nhọn và ngoặc vuông lồng vào nhau. Nhưng một khi đã nắm được tư duy logic của mảng must, filter hay should, bạn sẽ thấy nó cực kỳ mạch lạc và quyền năng.

Việc làm chủ cấu trúc này sẽ giúp anh em tự tin thiết kế những hệ thống tìm kiếm dữ liệu lớn cực kỳ nhanh, mượt và tối ưu hóa hiệu năng cho các ứng dụng backend hiện đại!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.