Truy vấn Boolean trong Elasticsearch

Khởi đầu với truy vấn Boolean

Truy vấn Boolean là một trong những cơ chế kết hợp truy vấn phổ biến nhất trong Elasticsearch. Nó cho phép xác định các điều kiện phức tạp bằng cách kết hợp nhiều mệnh đề con, trong đó chỉ những tài liệu thỏa mãn tất cả các điều kiện mới được trả về. Trong cấu trúc Boolean, có bốn loại mệnh đề con chính:

  • must – tương đương với toán tử AND
  • should – tương đương với toán tử OR
  • must_not – phủ định, tương đương với NOT
  • filter – dùng để lọc dữ liệu mà không ảnh hưởng đến điểm số (score)

Các phần tiếp theo sẽ trình bày từng loại mệnh đề qua ví dụ thực tế.

Chuẩn bị dữ liệu mẫu

Dưới đây là các tài liệu được tạo trong chỉ mục lqz:

PUT lqz/doc/1
{
  "name": "Cố Lão Nhị",
  "age": 30,
  "from": "gu",
  "desc": "da đen, vũ khí dài, tính cách thẳng thắn",
  "tags": ["đen", "dài", "thẳng"]
}

PUT lqz/doc/2
{
  "name": "Đại Nương Tử",
  "age": 18,
  "from": "sheng",
  "desc": "da trắng, xinh đẹp, dễ thương",
  "tags": ["trắng", "giàu", "xinh"]
}

PUT lqz/doc/3
{
  "name": "Long Tả Phi Phòng",
  "age": 22,
  "from": "gu",
  "desc": "mmp, chưa xem kỹ, không biết mô tả thế nào",
  "tags": ["tạo dữ liệu", "thật", "khó"]
}

PUT lqz/doc/4
{
  "name": "Đá Đá",
  "age": 29,
  "from": "gu",
  "desc": "thô nhưng tinh tế, giả vờ mạnh mẽ",
  "tags": ["thô", "lớn", "mạnh"]
}

PUT lqz/doc/5
{
  "name": "Vệ Hành Thủ",
  "age": 25,
  "from": "quảng vân đài",
  "desc": "như mây nhẹ che ánh trăng, như gió thoảng cuốn tuyết, mmp, cuối cùng lại không lấy Cố Lão Nhị!",
  "tags": ["bế nguyệt", "tu hào"]
}

Sử dụng must – Điều kiện đồng thời

Để tìm tất cả tài liệu có trường from bằng gu:

GET lqz/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "from": "gu"
          }
        }
      ]
    }
  }
}

Kết quả trả về 3 tài liệu: Cố Lão Nhị, Đá Đá, Long Tả Phi Phòng.

Để mở rộng thành điều kiện đồng thời, ví dụ: from = guage = 30:

GET lqz/doc/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "from": "gu" } },
        { "match": { "age": 30 } }
      ]
    }
  }
}

Chỉ có một tài liệu phù hợp: Cố Lão Nhị.

Sử dụng should – Điều kiện hoặc

Để tìm tài liệu thỏa mãn from = gu hoặc tags = bế nguyệt:

GET lqz/doc/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "from": "gu" } },
        { "match": { "tags": "bế nguyệt" } }
      ]
    }
  }
}

Kết quả bao gồm 4 tài liệu, vì bất kỳ điều kiện nào đúng đều được trả về.

Sử dụng must_not – Loại trừ điều kiện

Để tìm tài liệu không thuộc from = gu, không có từ khóa khỏe trong tags, và tuổi khác 18:

GET lqz/doc/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "from": "gu" } },
        { "match": { "tags": "khỏe" } },
        { "match": { "age": 18 } }
      ]
    }
  }
}

Chỉ có Vệ Hành Thủ là thỏa mãn tất cả điều kiện loại trừ.

Sử dụng filter – Lọc không ảnh hưởng điểm số

Để tìm tài liệu có from = gu và tuổi lớn hơn 25:

GET lqz/doc/_search
{
  "query": {
    "bool": {
      "must": [ { "match": { "from": "gu" } } ],
      "filter": {
        "range": {
          "age": { "gt": 25 }
        }
      }
    }
  }
}

Kết quả trả về Đá Đá (29 tuổi) và Cố Lão Nhị (30 tuổi).

Để tìm tài liệu có tuổi từ 25 đến 30 (bao gồm cả hai giới hạn):

GET lqz/doc/_search
{
  "query": {
    "bool": {
      "must": [ { "match": { "from": "gu" } } ],
      "filter": {
        "range": {
          "age": { "gte": 25, "lte": 30 }
        }
      }
    }
  }
}

Kết quả vẫn là hai tài liệu trên.

Đặc biệt lưu ý: Nếu sử dụng should trong khối bool nhưng đặt filter ở ngoài cấp, hệ thống sẽ báo lỗi cú pháp. Vì vậy, filter phải nằm bên trong bool.

Tóm tắt các mệnh đề

  • must: Tất cả điều kiện phải đúng (AND)
  • should: Ít nhất một điều kiện đúng (OR)
  • must_not: Không được thỏa mãn điều kiện (NOT)
  • filter: Dùng để lọc, không ảnh hưởng đến độ điểm (score)
  • range: Xác định phạm vi giá trị
  • gt: lớn hơn (>), gte: lớn hơn hoặc bằng (>=)
  • lt: nhỏ hơn (<), lte: nhỏ hơn hoặc bằng (<=)

Thẻ: Elasticsearch boolean query must should must_not

Đăng vào ngày 22 tháng 8 lúc 10:46