Quay lại

Bài 4: Full text query - Multi-match Query Chuyên mục Elasticsearch    2024-03-29    19 Lượt xem    15 Lượt thích    comment-3 Created with Sketch Beta. 0 Bình luận

Bài 4: Full text query - Multi-match Query

Multi-match Query

Trong Elasticsearch, multi-match query là một loại truy vấn linh hoạt cho phép bạn tìm kiếm các từ khóa trong nhiều field (hoặc nhiều field được chỉ định) cùng một lúc. Điều này hữu ích khi bạn muốn thực hiện tìm kiếm với các từ khóa trên nhiều field hoặc khi bạn không chắc chắn từ khóa sẽ xuất hiện trong field nào.

Dưới đây là cấu trúc cơ bản của một multi-match query:

{
  "query": {
    "multi_match": {
      "query": "your_query_string",
      "fields": ["field1", "field2", ...],
      "type": "best_fields" (hoặc "most_fields", "cross_fields", "phrase", "phrase_prefix", ...)
    }
  }
}​

Trong đó:

  • "query": là từ khóa hoặc cụm từ bạn muốn tìm kiếm.
  • "fields": là danh sách các field mà bạn muốn tìm kiếm. Bạn có thể chỉ định một hoặc nhiều field .
  • "type": là loại của multi-match query. Có một số loại khác nhau như "best_fields", "most_fields", "cross_fields", "phrase", "phrase_prefix",... Mỗi loại có cách hoạt động và ứng dụng khác nhau.

Thực hành

Data sample:

PUT clients
POST clients/_bulk
{"create": {"_id": 1}} 
{"id": 1, "first_name": "John", "last_name": "Doe", "email": "john.doe@gmail.com", "gender": "male", "age": 30, "group": "Sales", "country": "USA", "interests": "hiking, photography", "amount": 4000}
{"create": {"_id": 2}} 
{"id": 2, "first_name": "Alice", "last_name": "Smith", "email": "alice.smith@gmail.com", "gender": "female", "age": 25, "group": "Marketing", "country": "Canada", "interests": "traveling, painting, yoga", "amount": 5000}
{"create": {"_id": 3}} 
{"id": 3, "first_name": "Michael", "last_name": "Johnson", "email": "michael.johnson@gmail.com", "gender": "male", "age": 35, "group": "Development", "country": "Australia", "interests": "coding, gaming, hiking", "amount": 6000}
{"create": {"_id": 4}} 
{"id": 4, "first_name": "Emily", "last_name": "Brown", "email": "emily.brown@gmail.com", "gender": "female", "age": 28, "group": "Sales, Traveling", "country": "UK", "interests": "reading, cooking", "amount": 4500}
{"create": {"_id": 5}} 
{"id": 5, "first_name": "Daniel", "last_name": "Garcia", "email": "daniel.garcia@gmail.com", "gender": "male", "age": 40, "group": "Finance", "country": "Spain", "interests": "sports, music", "amount": 7000}
{"create": {"_id": 6}} 
{"id": 6, "first_name": "Emma", "last_name": "Lee", "email": "emma.lee@gmail.com", "gender": "female", "age": 33, "group": "Marketing", "country": "France", "interests": "yoga, meditation", "amount": 5500}
{"create": {"_id": 7}} 
{"id": 7, "first_name": "William", "last_name": "Wong", "email": "william.wong@gmail.com", "gender": "male", "age": 45, "group": "Sales", "country": "China", "interests": "gardening, fishing", "amount": 4800}
{"create": {"_id": 8}} 
{"id": 8, "first_name": "Olivia", "last_name": "Martinez", "email": "olivia.martinez@gmail.com", "gender": "female", "age": 29, "group": "Development", "country": "Mexico", "interests": "programming, hiking", "amount": 6200}
{"create": {"_id": 9}} 
{"id": 9, "first_name": "Will", "last_name": "Smith", "email": "will.chen@gmail.com", "gender": "male", "age": 32, "group": "Finance", "country": "Japan", "interests": "surfing, traveling", "amount": 6800}
{"create": {"_id": 10}} 
{"id": 10, "first_name": "Smith", "last_name": "Jones", "email": "smith.jones@gmail.com", "gender": "female", "age": 27, "group": "Marketing", "country": "Vietnam", "interests": "cooking, dancing", "amount": 5100}
{"create": {"_id": 11}} 
{"id": 11, "first_name": "Smiht", "last_name": "Dan", "email": "Smiht.jones@gmail.com", "gender": "female", "age": 27, "group": "Marketing", "country": "Vietnam", "interests": "reading, swiming", "amount": 5100}

Dưới đây là một ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query": "Smith cooking",
      "fields": ["interests", "first_name"]
    }
  }
}

Trong ví dụ này, Elasticsearch sẽ tìm kiếm các từ "Smith" và "cooking" trong các field "first_name" và "interests". Điều này giúp bạn tìm kiếm các từ khóa trên nhiều field cùng một lúc.

1. Fields và per-field boosting

  1. Các field có thể được chỉ định bằng ký tự đại diện (wildcards), ví dụ:
    • POST clients/_search
      {
        "query": {
          "multi_match": {
            "query": "Smith Development",
            "fields": ["*_name", "group"]
          }
        }
      }

      Khi bạn kết hợp pattern matching với nhiều trường trong Elasticsearch, cụ thể là trong trường hợp "*_name" kết hợp với các trường khác, Elasticsearch sẽ tìm kiếm trên tất cả các trường có tên kết thúc bằng "_name" cùng với các trường khác được liệt kê cụ thể.

      Ví dụ, nếu bạn có các trường như "first_name", "last_name" trong index của bạn thì nó sẽ tìm trong đó và kết hợp với trường "group".

  2. Các field riêng lẻ có thể được boosted bằng ký hiệu dấu mũ (^):
    • POST clients/_search
      {
        "query": {
          "multi_match": {
            "query": "Development coding programming Marketing",
            "fields": ["group", "interests^5"]
          }
        }
      }
    • "interests^3": Trong field fields, "interests^3" định nghĩa field "interests" với một hệ số tăng cường (boost) là 5. Điều này có nghĩa là tất cả các từ trong truy vấn tìm kiếm sẽ được tìm kiếm trong field "interests", và kết quả khớp trong field này sẽ nhận được một trọng số cao hơn gấp ba lần so với những fields "group"

2. Multi-match Query options 

Khi sử dụng multi-match query trong Elasticsearch, có một số options thường được sử dụng để điều chỉnh cách tìm kiếm và xử lý kết quả. Dưới đây là một số options phổ biến và ví dụ cụ thể cho mỗi option:

  1. operator: Xác định toán tử logic được sử dụng để kết hợp các từ trong truy vấn. Có thể là "OR" hoặc "AND". Mặc định là "OR".

    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "traveling painting",
          "fields": ["group", "interests"],
          "operator": "and"
        }
      }
    }
  2. type: Loại của multi-match query, xác định cách mà các field và từ khóa được xử lý.

    Ví dụ:

    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "surfing, traveling",
          "fields": ["group", "interests"],
          "type": "phrase"
        }
      }
    }
  3. fuzziness: Cho phép tìm kiếm các từ gần giống với các từ trong truy vấn.

    Ví dụ:

    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "emely broan",
          "fields": ["first_name", "last_name"],
          "fuzziness": "AUTO"
        }
      }
    }
  4. minimum_should_match: Xác định số lượng tối thiểu các từ cần khớp trong truy vấn.

    Tham số minimum_should_match không chỉ dành riêng cho tìm kiếm prefix hoặc fuzzy search, mà nó cũng được sử dụng trong các truy vấn khác như match, multi_match, bool, và dis_max để định rõ số lượng tối thiểu các điều kiện nên khớp trong một tập hợp các điều kiện. Ví dụ: 

    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "emely broan",
          "fields": ["first_name", "last_name"],
          "fuzziness": "AUTO",
          "minimum_should_match": "75%"
        }
      }
    }

    Trong truy vấn này, minimum_should_match được đặt thành "75%". Điều này có nghĩa là ít nhất 75% trong số các điều kiện tìm kiếm nên khớp với cụm từ được chỉ định ("emely broan" trong trường hợp này). Elasticsearch sẽ cố gắng tìm kiếm các trường hợp phù hợp với ít nhất 75% các điều kiện này.

    Bạn có thể thay đổi giá trị của minimum_should_match để điều chỉnh cách Elasticsearch xử lý việc khớp trong truy vấn của bạn.

    minimum_should_match giúp kiểm soát độ chặt chẽ của kết quả tìm kiếm bằng cách yêu cầu một số lượng tối thiểu các điều kiện được thỏa mãn. Điều này có thể hữu ích khi bạn muốn đảm bảo rằng các tài liệu trả về đáp ứng một số tiêu chí cụ thể trước khi được xem xét là kết quả khớp.

  5. boost: Cho phép tăng hoặc giảm trọng số của truy vấn trên các field khác nhau.

    Để sử dụng boost trong truy vấn multi-match trong Elasticsearch để tăng cường trọng số của một trường so với các trường khác, bạn có thể thêm giá trị boost cho mỗi trường trong truy vấn. Ví dụ:

    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "Development sports coding",
          "fields": ["group", "interests"],
          "boost": 2
        }
      }
    }
    
    
    Hoặc
    
    
    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "Development sports coding",
          "fields": ["group^2", "interests^5"]
        }
      }
    }
    
  6. max_expansions: Được sử dụng để giới hạn số lần mở rộng cho phép trong quá trình tìm kiếm "prefix" hoặc "fuzzy" search.

    Ví dụ:

    POST clients/_search
    {
      "query": {
        "multi_match": {
          "query": "Smiht",
          "fields": ["first_name", "last_name"],
          "fuzziness": "AUTO",
          "max_expansions": 1
        }
      }
    }

Những options này có thể được sử dụng độc lập hoặc kết hợp với nhau để tinh chỉnh truy vấn multi-match để đáp ứng nhu cầu tìm kiếm cụ thể.

3. Multi-match Query type

Trong Elasticsearch, multi_match query cung cấp các loại khác nhau để điều chỉnh cách tìm kiếm và xử lý kết quả. Dưới đây là một số loại phổ biến của multi_match query và cách sử dụng của từng loại:

"best_fields":

Tìm kiếm trên tất cả các field được chỉ định và gán điểm cao nhất cho các document khớp tốt nhất.

Trong truy vấn bên dưới của mình, multi_match sử dụng best_fields làm loại tìm kiếm, cho phép Elasticsearch tìm kiếm query trong hai  fields first_namelast_name, và trả về kết quả từ trường có điểm số cao nhất.

Bạn có thể sử dụng tham số type: "best_fields" để đảm bảo rằng chỉ kết quả từ trường có điểm số cao nhất sẽ được trả về, giúp cải thiện chất lượng kết quả tìm kiếm.

Ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query": "Smith",
      "fields": ["first_name", "last_name"],
      "fuzziness": "AUTO",
      "type": "best_fields"
    }
  }
}

"most_fields":

Tìm kiếm trên tất cả các field được chỉ định và tính tổng điểm cho mỗi document dựa trên số lượng field khớp.

Trong Elasticsearch, khi bạn sử dụng loại truy vấn multi_match với option "most_fields", Elasticsearch sẽ tìm kiếm trên tất cả các trường được chỉ định và tính tổng điểm cho mỗi tài liệu dựa trên số lượng trường khớp với từ khóa tìm kiếm.

Loại most_fields sẽ trả về kết quả từ tất cả các trường được chỉ định, không quan trọng điểm số của mỗi trường. Điều này giúp cung cấp sự linh hoạt cho việc tìm kiếm và trả về kết quả từ nhiều trường khác nhau.

Ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query": "Smith",
      "fields": ["first_name", "last_name"],
      "type": "most_fields"
    }
  }
}

"cross_fields":

Khi sử dụng loại tìm kiếm cross_fields trong truy vấn multi_match của Elasticsearch, bạn muốn tìm kiếm cùng một cụm từ hoặc từ khóa trong nhiều trường và coi chúng như một nhóm. Loại tìm kiếm này thường hữu ích khi bạn muốn tìm kiếm thông tin trong nhiều trường khác nhau và coi chúng như một đối tượng đồng nhất.

Ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query":      "Will Smith",
      "type":       "cross_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator": "and"
    }
  }
}

Trong trường hợp của chúng ta, từ "Will Smith" được coi như một nhóm và tìm kiếm trong các trường "first_name" và "last_name". Mục đích là tìm kiếm một tài liệu nơi cả hai từ "Will" và "Smith" đều xuất hiện trong bất kỳ trường "first_name" hoặc "last_name" nào.

Dưới đây là giải thích:

+blended("will",  fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])

Elasticsearch sẽ tìm kiếm từng từ trong các trường được chỉ định và kết hợp kết quả từ cả hai tìm kiếm này để trả về kết quả nơi cả hai từ đều xuất hiện.

"phrase":

Khi bạn thiết lập loại tìm kiếm của multi_match thành phrase, Elasticsearch sẽ tìm kiếm cho một cụm từ chính xác, tức là tìm kiếm cho cụm từ xuất hiện chính xác theo thứ tự trong các trường được chỉ định.

Ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query":      "traveling",
      "type":       "phrase",
      "fields":     [ "interests" , "group"]
    }
  }
}

"phrase_prefix":

Tìm kiếm các cụm từ trong field với một phần đầu tiên đã biết. Điều này cho phép bạn tìm kiếm các từ bắt đầu bằng một phần cụ thể.

Ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query":      "traveli, ",
      "type":       "phrase_prefix",
      "fields":     [ "interests" , "group"]
    }
  }
}

"bool_prefix":

bool_prefix là một loại truy vấn được sử dụng trong Elasticsearch để tìm kiếm các từ hoặc cụm từ bắt đầu bằng một tiền tố cụ thể. Truy vấn này thường được sử dụng trong các trường hợp muốn tìm kiếm các từ hoặc cụm từ bắt đầu bằng một chuỗi ký tự nhất định.

POST clients/_search
{
  "query": {
    "multi_match": {
      "query":      " sur",
      "type":       "bool_prefix",
      "fields":     [ "interests" , "group"]
    }
  }
}

4. Multi-match tie_breaker

Trong Elasticsearch, tie_breaker là một tùy chọn trong truy vấn multi_match query, được sử dụng để kiểm soát cách tính toán điểm số cho các document khi có nhiều field khớp với truy vấn tìm kiếm.

Khi bạn tìm kiếm trên nhiều field với multi_match query, mỗi document có thể khớp với truy vấn trên nhiều field khác nhau. Trong field hợp này, tie_breaker xác định cách tính toán điểm số cuối cùng cho mỗi document dựa trên điểm số của mỗi field khớp.

Giá trị của tie_breaker là một số thực từ 0 đến 1. Khi tie_breaker được đặt là 0, điểm số cuối cùng của mỗi document sẽ được xác định bởi field có điểm số cao nhất. Khi tie_breaker tăng lên, điểm số của các field khớp thấp hơn cũng được tính vào điểm số cuối cùng, nhưng với một tỷ lệ thấp hơn so với field có điểm số cao nhất.

Ví dụ:

POST clients/_search
{
  "query": {
    "multi_match": {
      "query":      "Will Smith",
      "type":       "cross_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator": "and",
      "tie_breaker": 0.3
    }
  }
}

Trong ví dụ này, tie_breaker được đặt là 0.3. Điều này có nghĩa là khi tính điểm số cuối cùng của mỗi document, 70% của điểm số sẽ được xác định bởi field có điểm số cao nhất, và 30% sẽ được chia ra cho các field khác nếu chúng cũng khớp với truy vấn tìm kiếm.

 
 

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday