You are on page 1of 31

Multifield search

Nhóm 14
Các Thành Viên Trong Nhóm:
Mai Vũ Hà Mai
Đoàn Lương Hiếu
Nguyễn Kim Hiếu
Nguyễn Công Đạt
A.Giới thiệu về elastic search
1. Định nghĩa
- Elasticsearch được xem là một search engine, hoạt động thực chất như 1 web server với khả năng tìm kiếm nhanh
chóng thông qua giao thức RESTful, sở hữu khả năng phân tích và thống kê dữ liệu vô cùng hiệu quả.
2. Cách thức hoạt động
- Elasticsearch hoạt động như một Cloud Server theo cơ chế RESTful, tức là từ Client tạo ra các HTTP Request
(GET, PUT …) kèm dữ liệu dạng JSON để tương tác với Elasticsearch (POST, PUT, DELETE, GET,…).
- Để tạo ra Http Request gửi đến Elasticsearch thì bạn có thể dùng các loại ngôn ngữ khác nhau để xây dựng hệ
thống: Java, PHP, Ruby, .Net, Python,…
- Tất cả dữ liệu được lưu vào Elasticsearch đều được đánh Index(chỉ mục), vì thế hiệu năng tìm kiếm
của Elasticsearch rất cao.
3. Ứng dụng của elastic search
- Elasticsearch đã trở thành công cụ tìm kiếm (search engine) thông dụng nhất và được sử dụng rộng rãi
cho các công việc liên quan đến chỉ mục và tìm kiếm tài liệu, phân tích dữ liệu …
4. Ưu, nhược điểm của elastic search
• Ưu điểm :
- Cho phép tìm kiếm dữ liệu một cách nhanh chóng với hiệu năng cao gần như là real-time
- Hỗ trợ hầu hết mọi loại dữ liệu, trừ những kiểu dữ liệu không hỗ trợ hiển thị dưới dạng văn bản (text).
- Lưu trữ dữ liệu full-text và quản lý vòng đời chỉ mục, cho phép người dùng truy xuất và phân tích, tổng
hợp lượng dữ liệu rất lớn với tốc độ cao, hiệu quả hơn.
- Có thể hoạt động được trên nhiều nền tảng khác nhau, đồng thời tương tác, hỗ trợ nhiều ngôn ngữ lập
trình
• Nhược điểm:
- ElasticSearch kém bảo mật hơn so với các hệ quản trị cơ sở dữ liệu hiện nay.
- Không phù hợp với những hệ thống thường xuyên cập nhật dữ liệu do sẽ rất tốn kém trong việc lập chỉ
mục dữ liệu.
- Elasticsearch được thiết kế cho mục đích tìm kiếm nên thường không dùng làm DB chính.
B: Nội dung

Multifield search
Multiple Query Strings (Nhiều chuỗi truy vấn)
Nhiều chuỗi truy vấn nhằm để tìm kiếm trên nhiều trường với các điều kiện cụ thể được viết ra với mệnh đề match và kết
hợp chúng lại bằng truy vấn bool.
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "War and Peace" }},
{ "match": { "author": "Leo Tolstoy" }}

]
}
}
}

 Truy vấn bool chạy từng mệnh đề match cộng dồn điểm số đưa ra điểm số cho mỗi tài liệu các tài liệu khớp với càng
nhiều mệnh đề điểm càng cao.
Prioritizing Clauses (ưu tiên các mệnh đề)
GET /_search
{
"query": {

Ưu tiên của các mệnh đề là


"bool": {
"should": [

việc tăng trọng số cho mệnh đề


{ "match": { (1)
"title": {

ta quan tâm trong truy vấn bool "query": "War and Peace",
"boost": 2

bằng cách dùng tham số boost, }}},


{ "match": { (1)

mệnh đề được ưu tiên sẽ đặt giá "author": {


"query": "Leo Tolstoy",

trị boost lớn hơn. }}},


"boost": 2

{ "bool": { (2)
Giá trị boost “tốt nhất” nằm "should": [

giữa 1 và 10, có khi là 15 các giá


{ "match": { "translator": "Constance Garnett" }},
{ "match": { "translator": "Louise Maude" }}

trị cao hơn đem lại ít tác dụng


]
}}

hơn do số điểm được chuẩn hóa.


]
}
}
}
Single Query String( Chuỗi truy vấn đơn)

- Chuỗi truy vấn đơn nhầm tìm kiếm trên nhiều trường bằng cách nhập thuật ngữ tìm kiếm trên một
trường duy nhất.
- Để thực thi truy vấn đơn đạt được kết quả tốt nhất không có một giải pháp đơn giản, bạn cần sự hiểu
biết về dữ liệu và cách sử dụng những công cụ phù hợp.
Know Your Data(hiểu dữ liệu của bạn)

- Khi thực hiện một chuỗi truy vấn đơn bạn thường xuyên gặp phải các tình huống:
 Các trường tốt nhất: các từ đi cùng nhau sẽ có ý nghĩa hơn các từ riêng lẻ, các trường có mối liên hệ
với nhau được coi như đối nghịch nhau, điểm số nên được lấy từ trường khớp nhiều nhất.
 Phần lớn các trường: chia dữ liệu ra làm nhiều trường mỗi cái có một dãy phân tích riêng. Trường
chính có thể bao gồm các từ ở dạng từ gốc, từ đồng nghĩa, và các từ bị loại bỏ dấu thanh, hay trọng
âm, trường chính được dùng để ăn khớp với nhiều tài liệu. Nó được dùng làm phụ lục cho các trường
khác để đem lại sự ăn khớp chính xác hơn. Các trường này như các tín hiệu để tăng điểm liên quan
cho mỗi tài liệu ăn khớp.
 Các trường đan xen: Một số đối tượng thông tin để nhận biết chúng nằm rải rác ở nhiều trường khi
đó ta cần xem các trường này như một trường lớn nhầm tìm kiếm càng nhiều từ càng tốt.
I. Các trường tốt nhất
- Dựa vào cách truy vấn bool tính điểm nếu 2 từ cùng xuất hiện trên chỉ một trường sẽ có mức ưu tiên ít hơn nếu một từ
lập lại ở nhiều trường.
- Truy vấn dis_max

Truy vấn dis_max tức “Disjunction Max Query” trả về bất cứ tài liệu nào khớp với bất cứ truy vấn nào, và trả về điểm của
truy vấn khớp nhiều nhất.
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Brown fox" }},
{ "match": { "body": "Brown fox" }}
]
}
}
}
 Căn chỉnh truy vấn các trường tốt nhất
- Do truy vấn dis_max chọn trường ăn khớp nhiều nhất và bỏ qua các trường còn lại nên sẽ không xảy
ra việc những tài liệu ăn khớp ở nhiều trường sẽ có điểm cao hơn tài liệu chỉ ăn khớp ở 1 trường.
 Tie_breaker
- Ta có thể tính điểm của các mệnh đề ăn khớp bằng cách đặt tham số tie_breaker giúp truy vấn
dis_max hoạt động như một trung gian giữa dis_max và bool.
- Tie_breaker giúp mọi mệnh đề ăn khớp đều được tính nhung mạnh đề nhưng mệnh đề ăn khớp nhiều
nhất được tính nhiều hơn
 Truy vấn multi_match
- Truy vấn multi_match đem lại một cách viết tắt tiện lợi để chạy cùng truy vấn đối với nhiều trường.
- Truy vấn này sẽ mặc định theo loại best_fields, tức là nó tạo ra một truy vấn match cho mỗi trường và
kết hợp chúng lại trong một truy vấn dis_max.
 Sử dụng ký tự đại diện trong tên trường
- Tên các trường có thể được định rõ bằng các ký tự đại diện: Bất cứ trường nào ăn khớp với cú pháp
sẽ được đưa vào kết quả tìm kiếm.
Ưu tiên từng trường cụ thể
Các trường được ưu tiên bằng cách thêm dấu mũ(^): thêm ^boost sau tên trường trong đó boost là số
thực.
GET /books/_search
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title^2", "description" ] (1)
}
}
}
II. Phần lớn các trường
- Tìm kiếm toàn văn bản (Full text search) là một trận chiến giữa gọi lại – trả về các tài liệu liên quan –
và độ chính xác – không trả về các tài liệu không liên quan. Mục tiêu là để trình bày cho người dùng
các tài liệu liên quan nhất ở trang đầu kết quả.
 VD. Để cải thiện việc gọi về, ta sẽ giăng lưới rộng – ta không chỉ tính đến các tài liệu ăn khớp
hoàn toàn với các thuật ngữ tìm kiếm của người dùng, mà còn cả những tài liệu ta cho là liên quan
tới truy vấn. Nếu người dùng tìm kiếm “fast brown fox” (cáo nâu chạy nhanh), một tài liệu chứa
“fast foxes” (các loại cáo chạy nhanh) sẽ là một kết quả hợp lý để trả về.
 Nếu như tài liệu liên quan duy nhất của ta lại chứa “fast foxes”, nó sẽ hiện lên đầu danh sách tìm
kiếm. Nhưng đương nhiên, nếu ta có 100 tài liệu chứa “quick brown fox”, thì các tài liệu chỉ chứa
“fast foxes” có thể coi như ít liên quan, và ta nên đẩy chúng ra sau danh sách. Sau khi tính đến các
tài liệu có thể ăn khớp, ta cần đảm bảo rằng những tài liệu tốt nhất sẽ được lên đầu
- Trường chính có thể bao gồm các từ ở dạng từ gốc, từ đồng nghĩa, và các từ
bị loại bỏ dấu thanh, hay trọng âm, trường chính được dùng để ăn khớp với
nhiều tài liệu.
 Dùng thuật toán tìm từ gốc, VD: các từ jumps, jumping và jumped theo từ
gốc của chúng: jump qua đó khi người dùng tìm kiếm jumped vẫn có thể
tìm thấy các tài liệu có jumping.
 + Tính đến cả các từ đồng nghĩa, VD: jump, leap, hop.
 + Loại bỏ dấu thanh trọng âm, VD: ésta, está, esta đều được đánh chỉ mục
là esta.
- Nếu có 2 tài liệu chứa jumped và jumping thì tài liệu chứa từ cần tìm
jumped xếp cao hơn.
- Ta có thể thực hiện bằng cách đánh chỉ mục cùng 1 phần chữ trong các
trường khác nhau sẽ đem lại sự chính xác hơn. Các trường có vai trò như tín
hiệu để làm tăng sự ăn khớp, càng nhiều trường càng tốt.
- Tài liệu được đưa vào danh sách tìm kiếm nếu nó ăn khớp với trường chính,
càng ăn khớp với các trường tín hiệu càng được nhiều điểm.
 Ánh xạ nhiều trường
- Đảm bảo trường của ta được đánh dấu chỉ mục 2 lần: một lần ở dạng gốc một lần ở dạng cụ
thể.
- Để làm điều này ta sử dụng các đa trường tiếp đó đánh chỉ mục cho mỗi tài liệu.
- Ta đang dùng trường title dễ ăn khớp để tìm được càng nhiều tài liệu càng tốt – để cải thiện
việc gọi lại – Nhưng ta lại dùng trường title.std làm tín hiệu để đẩy các kết quả liên quan
nhất lên đầu.
- Để ưu tiên một trường cụ thể ta thêm giá trị boost
III. Tìm kiếm đối tượng ở các trường đan xen
- Tìm kiếm đối tượng như người, sản phẩm, địa chỉ dấu hiệu nhận biết của chúng nằm ở nhiều trường.
Ta dùng một chuỗi truy vấn duy nhất áp dụng trên nhiều trường bằng cách xem chúng như một trường
lớn.
 Một hướng tiếp cận ngây thơ
- Thay vì thực hiện truy vấn lần lượt trên tất cả các trường ta có thể dùng truy vấn multi_match, và đặt
type bằng most_fields để báo rằng ta muốn cộng dồn điểm của tất cả các trường có ăn khớp.
- Code 1:
{
"query": {
"bool": {
"should": [
{ "match": { "street": "Poland Street W1V" }},
{ "match": { "city": "Poland Street W1V" }},
{ "match": { "country": "Poland Street W1V" }},
{ "match": { "postcode": "Poland Street W1V" }}
]
}
}
}
Code 2:

"query": {

"multi_match": {

"query": "Poland Street W1V",

"type": "most_fields",

"fields": [ "street", "city", "country", "postcode" ]

}
 Vấn đề tiếp cận most_fields
- Một số vấn đề khó thấy của hướng tiếp cận most_fields:
 + Nó được thiết kế để tìm số trường nhiều nhất ăn khớp với bất cứ từ nào, thay vì tìm các
từ ăn khớp nhất trên tất cả các trường.
 + Nó không thể sử dụng các tham số operator hay minimum_should_match để giảm tác
động của các kết quả ít liên quan.
 + Tần suất xuất hiện của các từ ở mỗi trường là khác nhau và có thể xen lẫn vào nhau và
tạo ra các kết quả không được sắp xếp tốt.
Truy vấn tập trung vào trường
- Cả 3 vấn đề nói trên đều tập trung vào trường thay vì từ tìm kiếm nó tìm các trường ăn khớp trong khi
chúng ta quan tâm các từ ăn khớp nhất.
 Vấn đề 1: so sánh cùng 1 từ trên nhiều trường
- Hãy nghĩ về cách mà truy vấn most_fields được thi hành: Elasticsearch tạo ra một truy vấn match
riêng biệt cho mỗi trường rồi gộp các truy vấn match này lại trong một truy vấn bool bên ngoài.
- Ta nhận thấy tài liệu chỉ ăn khớp với một từ trên 2 trường có điểm số cao hơn tài liệu ăn khớp 2 từ
trên cùng một trường.
 Vấn đề 2: cắt gọn đuôi dài
- Ta đã bàn về việc sử dụng toán tử and hoặc là tham số minimum_should_match để cắt gọn
cái đuôi dài chứa đầy các kết quả không liên quan.
- Tuy nhiên, với best_fields hoặc most_fields, các tham số được chuyển cho các truy vấn
match được tạo ra. Nói cách khác, sử dụng toán tử and nghĩa là mọi từ khóa đều phải có
mặt trong cùng một trường, rõ ràng là sai, sẽ khó tìm được một tài liệu thỏa mãn truy vấn
này.
 Vấn đề 3: tần suất xuất hiện của từ
- Tần suất xuất hiện của từ(Term frequency/TF): một từ xuất hiện càng nhiều
trong tài liệu thì tài liệu đó càng liên quan.
- Tần số nghịch của 1 từ trong tập văn bản(Inverse document frequency/IDF):
Một từ càng xuất hiện nhiều ở một trường trong mọi tài liệu được đánh chỉ
mục, thì từ đó càng ít liên quan.
- Khi tìm kiếm trên nhiều trường, TF/IDF có thể đem lại một số kết quả đáng
ngạc nhiên
- VD: tìm “Peter Smith” bằng các trường first_name và last_name. Peter là một tên phổ biến
còn Smith là một họ phổ biến – cả 2 đều sẽ có IDF thấp. Nhưng nếu như ta có một người
khác ở trong chỉ mục tên là Smith Williams, Smith mà là tên thì rất hiếm nên sẽ có IDF cao.
- Chỉ số IDF cao của Smith ở tên áp đảo 2 số IDF thấp của Peter là tên và Smith nên rất có
thể sẽ cho Smith Williams lên trên Peter Smith mặc dù người thứ 2 ăn khớp nhiều hơn so
với người thứ nhất.
 Giải pháp
- Các vấn dề này pháp sinh vì ta đang đối mặt với nhiều trường nên nếu ta gộp các trường này thành
một trường duy nhất các vấn đề sẽ được giải quyết.
- Trong khi cách này hiệu quả, ta không thích phải tạo dữ liệu dư thừa. Thay vào đó, Elasticsearch cho
chúng ta 2 giải pháp – một cách ở thời điểm đánh chỉ mục và một cách ở thời điểm tìm kiếm.
Các trường _all tự chọn
- Trường _all đánh chỉ mục các giá trị từ tất cả các trường khác như thể một xâu lớn. Tuy
vậy, tất cả các trường được đánh chỉ mục thành một trường thì không được linh hoạt cho
lắm. Sẽ thật tốt nếu ta có thể có một trường _all tự chọn cho tên người, và một trường _all
tự chọn khác cho địa chỉ. Elasticsearch cung cấp cho ta tính năng này thông qua tham số
copy_to trong một ánh xạ trường.
Truy vấn các trường đan xen
- Để thực hiện giải pháp lúc đang tìm kiếm ta dùng truy vấn multi_match với kiểu cross_fields. Kiểu
cross_fields tiếp cận theo hướng tập trung vào từ, khá là khác so với kiểu tập trung vào trường của best_fields
và most_fields. Nó xem tất cả các trường như một trường lớn, và tìm mỗi từ ở bất cứ trường nào.
- Kiểu cross_fields đầu tiên sẽ phân tích chuỗi truy vấn để tạo ra một danh sách các từ, rồi sau đó nó tìm từng
từ trong mọi trường. Qua đó giải quyết 2 trong 3 vấn đề nêu trên để lại vấn đề về tần số nghịch của từ trong
văn bản.
- Cross_fields giải quyết vấn này bằng các “trộn” tần số nghịch của từ trong một tập văn bản nhiều trường. Nói
các khác nó tìm IDF của của các trường rồi sửa dụng kết quả thấp nhất làm IDF của các trường đó.
- Để cho truy vấn dạng cross_fields hoạt động tối ưu, mọi trường đều nên có trình phân tích giống nhau. Các
trường có cùng trình phân tích sẽ được gộp với nhau như các trường đã hợp vào nhau.
Ưu tiên từng trường
- Một trong những thế mạnh của việc sử dụng cross_fields thay vì tự tạo trường _all là việc bạn có thể
ưu tiên các trường cụ thể ở thời gian truy vấn.
- Để ưu tiên trường bạn muốn tìm kiếm có thể thêm dấu mũ(^) như đã nói trên.

- Lợi thế của khả năng ưu tiên các trường cụ thể nên được cân đo với hao tổn trong việc phải truy vấn
nhiều trường thay vì chỉ truy vấn một trường _all. Hãy dùng bất cứ cách nào trong 2 cách trên tùy
theo cách nào có lợi nhất cho tình huống của bạn.
Các trường có giá trị cụ thể

 Các trường not_analyzed có giá trị cụ thể nên việc trộn lẫn các trường not_analyzed với các trường
analyzed trong truy vấn multi_match là điều không hề hữu ích.
Thank you!

You might also like