Tìm kiếm có cấu trúc trong Elasticsearch với các truy vấn nâng cao

Elasticsearch hỗ trợ hai loại tìm kiếm chính: tìm kiếm toàn văn và tìm kiếm có cấu trúc. Loại thứ hai tập trung vào dữ liệu mang tính định lượng hoặc định dạng rõ ràng như số, ngày tháng, hay giá trị boolean — những trường có thể so sánh chính xác bằng các phép logic như khoảng giá trị, bằng, lớn hơn, nhỏ hơn.

Nhập dữ liệu mẫu để thực hành

curl -XPOST 'http://hadoop01:9200/school/student/_bulk' -d '
{ "index": { "_id": 1 }}
{ "name": "liubei", "age": 20, "gender": "male", "dob": "1996-01-02", "interests": "fishing and girls" }
{ "index": { "_id": 2 }}
{ "name": "guanyu", "age": 21, "gender": "male", "dob": "1995-01-02", "interests": "fishing" }
{ "index": { "_id": 3 }}
{ "name": "zhangfei", "age": 18, "gender": "male", "dob": "1998-01-02", "interests": "traveling" }
{ "index": { "_id": 4 }}
{ "name": "diaocan", "age": 20, "gender": "female", "dob": "1996-01-02", "interests": "traveling and sports" }
{ "index": { "_id": 5 }}
{ "name": "panjinlian", "age": 25, "gender": "female", "dob": "1991-01-02", "interests": "traveling and wusong" }
{ "index": { "_id": 6 }}
{ "name": "caocao", "age": 30, "gender": "male", "dob": "1988-01-02", "interests": "xiaoqiao" }
{ "index": { "_id": 7 }}
{ "name": "zhaoyun", "age": 31, "gender": "male", "dob": "1997-01-02", "interests": "traveling and music" }
{ "index": { "_id": 8 }}
{ "name": "xiaoqiao", "age": 18, "gender": "female", "dob": "1998-01-02", "interests": "caocao" }
{ "index": { "_id": 9 }}
{ "name": "daqiao", "age": 20, "gender": "female", "dob": "1996-01-02", "interests": "traveling and history" }'

1. Truy vấn đơn giản với match_all

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "match_all": {}
  }
}'

Truy vấn này trả về tất cả tài liệu — không phù hợp với nhu cầu thực tế và dễ gây quá tải hệ thống. Cần sử dụng các truy vấn có điều kiện cụ thể hơn.

2. Tìm theo từ khóa trong trường cụ thể

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "match": { "interests": "traveling" }
  }
}'

Nếu muốn tìm người thích du lịch và không phải nam giới, không thể dùng nhiều trường trong một match. Phải dùng truy vấn kết hợp (boolean).

3. Boolean query với must, must_not, should

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "bool": {
      "must": { "match": { "interests": "traveling" } },
      "must_not": { "match": { "gender": "male" } }
    }
  }
}'

Dùng should nếu muốn điều kiện là tùy chọn:

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "bool": {
      "must": { "match": { "interests": "traveling" } },
      "should": { "match": { "gender": "male" } }
    }
  }
}'

4. Term query — khớp chính xác

Dùng để tìm giá trị nguyên thủy không qua phân tích: số, ngày, boolean, hoặc chuỗi không được tokenize.

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "bool": {
      "must": { "term": { "interests": "traveling" } },
      "should": { "term": { "gender": "male" } }
    }
  }
}'

5. Terms query — khớp nhiều giá trị

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "bool": {
      "must": { "terms": { "interests": ["traveling", "history"] } }
    }
  }
}'

Lưu ý: term yêu cầu khớp chính xác từng term, còn match sẽ phân tích và khớp từng phần.

6. Range query — tìm theo khoảng giá trị

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "range": {
      "age": { "gt": 20, "lte": 25 }
    }
  }
}'

7. Exists/Missing — kiểm tra sự tồn tại của trường

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "exists": {
      "field": "age"
    }
  }
}'

8. Kết hợp nhiều điều kiện với bool

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "bool": {
      "must": [
        { "term": { "interests": "traveling" } },
        { "range": { "age": { "gt": 20, "lt": 30 } } }
      ]
    }
  }
}'

9. Tách biệt truy vấn và lọc để tối ưu hiệu năng

Dùng filter cho các điều kiện không cần tính điểm relevance — giúp cache kết quả tốt hơn.

curl -XGET 'hadoop01:9200/school/student/_search?pretty' -d '
{
  "query": {
    "bool": {
      "must": { "match": { "interests": "traveling" } },
      "filter": [ { "term": { "age": 20 } } ]
    }
  }
}'

Thẻ: Elasticsearch structured-search boolean-query term-query range-query

Đăng vào ngày 4 tháng 6 lúc 19:23