+7

Một số query phổ biến trong Elasticsearch

Bài viết sẽ giới thiệu một số queries phổ biến trong elasticsearch như là match, phrase_match, prefix, term, multi_match, và bool.

Tổng quan về một số queries

Query Name Chức năng Query mẫu Matching Text Not Matching Text
match - Matches nếu 1 term trong query đó match
- Càng nhiều term match thì score của document đó sẽ lớn
- Query search sẽ được apply analyzer config cho field search đó hoặc để mặc định (nếu không set)
cat dog - cat and dog
- The blue cat
- The cat is blue
- The dog is white
- The blue
- The white
phrase_match - Chỉ matches nếu các term match có cùng thứ tự và liên tiếp nhau cat dog - cat dog are green
- green and cat dogs
- dog cat are green
- cat and dog are green
prefix Nó tương tự như pharse_match query nhưng nó sẽ match chính xác term FR VN - FR VN2017
- FR VN-2017
- FRVN2017
- FRVN-2017
term - Query trên truy vấn mình truyền vào, analyzer sẽ không được apply dog - this is a dog - there are many dogs here
- Dog is green
multi_match - apply match query trên nhiều field khác nhau -field1: dog
- field2: cat
match với field1 chứa dog hoặc field2 chứa cat - Nếu cả 2 fields không chứa bất cứ từ liên quan đến dog và cat
bool Applies nhiều queries khác nhau must: {field1: dog}, must_not: {field2: cat} match với document với field1 chứa dog và field2 không chứa cat Nếu document có field1 chứa dog và field2 chứa cat
- hoặc field2 chứa cat
-hoặc field1 không chứa dog

Ví dụ minh họa

Ở dưới chúng ta sẽ đi sâu vào một số query cơ bản như là match, pharse_match, hay là term, bool còn multi_match tương tự với match có điều nó match với nhiều field khác nhau.

  • Giả sử ta có một User index với mapping như sau
{
  "users" : {
    "mappings" : {
      "user" : {
        "properties" : {
          "name" : {
            "type" : "string"
          }
				}
			}
		}
	}
}

=> Khi không gán analyzer cho field đó thì mặc định sẽ là default, sẽ phân tích các từ theo space.

  • Chúng ta sẽ tạo ra 3 document chứa thông tin name của user (3 bản ghi này sẽ dùng để so sánh các queries khác nhau)

Document 1

{name: "Nguyen Thi Ngoc"}

Document 2

{name: "Ruby Nguyen"}

Document 3

{name: "Ngoc Nguyen Thi"}

Match query

Match query là một query cơ bản và nổi bật nhất của elasticsearch, nó được sửa dụng để search cho cả field được analyzed và not_analyzed. Khi search theo field được analyzed thì query search sẽ được phân tích theo đúng analyzed đó. Hoặc theo mặc định của elasticsearch nếu nó không chỉ định. Chúng ta cùng xét query sau

{
  "query": {
    "match": {
      "name": "Nguyen"
    }
  }
}

Query này sẽ search tất cả user có name là Nguyen Với các bản ghi trên, field name được analyzer mặc định nên nó sẽ phân tích các từ như sau:

Document 1: "Nguyen Thi Ngoc"
=> ["Nguyen", "Thi", "Ngoc"]
Document 2: "Ruby Nguyen"
=> ["Ruby", "Nguyen"]
Document 3: "Ngoc Nguyen Thi"
=> ["Ngoc", "Nguyen", "Thi"]

Dựa vào đó ta có bảng phân tích index như sau

Document 1 Document 2 Document 3
Nguyen x x x
Thi x x
Ngoc x x
Ruby x

=> match_query chỉ cần document nào có chứa query thì sẽ trả về kết quả. Ở trên ta query Nguyen và 3 document đều có, kết quả sẽ trả về cả 3 document.

Phrase query

Được sử dụng khi chúng ta muốn match các từ với thứ tự giống như query chúng ta mong muốn. Ví dụ search user có name Thi Ngoc

{
    "query": {
        "match_phrase" : {
            "name" : "Thi Ngoc"
        }
    }
}

Theo như bảng phân tích trên, nếu dùng match query thì sẽ trả về cho ta Document 1Document 3. Nhưng thực tế ta đang muốn trả về những user có Thi Ngoc liền kề nhau và được order theo đúng thứ tự mà ta đã search chứ không phải trả về những name như là Ngoc Thi ... Thì match_phrase giải quyết vấn đề này, nó sẽ xem xét thứ tự của term search => chỉ trả về Document 1

Term

Thường được search với chính xác với term đã chỉ định, query search sẽ không được analyzed. Ví dụ đối với user ngoài name còn có email với tokenizer: uax_url_email => nó sẽ phân tích email và trả về kết quả như sau:

Document 1

{email: "nguyen.thi.ngoc@framgia.com"}
=> ["nguyen.thi.ngoc@framgia.com", "nguyen.thi.ngoc", "nguyen", "thi", "ngoc", "framgia.com", "framgia", "com"]

Document 2

{email: "nguyenngoc@gmail.com"}
=> ["nguyenngoc@gmail.com", "nguyenngoc", "gmail.com", "gmail", "com"]

Document 3

{email: "nguyenngoc1234@gmail.com"}
=> ["nguyenngoc1234@gmail.com", "nguyenngoc1234", "nguyenngoc", "1234", "gmail.com", "gmail", "com"]

Term query sẽ không analyzed query search, nó sẽ match chính xác term với document, nếu document nào có term đó thì sẽ trả về kết quả. Ví dụ search com

{
      term: {
         email: "com"
      }
}

Ta thấy cả 2 document đều match với term com => kết quả sẽ trả về cả 3 user đó. Ví dụ với nguyenngoc1234 Thông thường search với match => nó sẽ được phân tích thành ["nguyenngoc", "1234"] => nó sẽ match với Document 2Document 3. Với term query nó sẽ match document nào có chính xác term nguyenngoc1234 và trả về kết quả => return Document 3 .

Bool

  • Được dùng để applies nhiều query khác nhau. Ví dụ ta muốn search email hoặc match với framgia hoặc nguyenngoc
{
  "query": {
    "bool" : {
         "should" : [
            { "term" : { "email" : "framgia" } },
            { "term" : { "email" : "nguyenngoc" } }
         ]
		}
  }
}

=> nó sẽ return về cả 3 document. Trong should bạn muốn applies thêm những condition thì sẽ dùng bool để bao những condition đó trong should (giống dạng nested vậy).

Tổng kết

Bài viết đã giới thiệu một chút về những query phổ biến với Elasticsearch. Hy vọng bạn sẽ chọn đúng loại query đúng với yêu cầu.


All Rights Reserved

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