You are on page 1of 13

ĐẠI HỌC QUỐC GIA HÀ NỘI

TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN


---- 🙞🙜 🕮 🙞🙜 ----

BÁO CÁO THUYẾT TRÌNH


CHỦ ĐỀ: MULTIFIELD SEARCH
Sinh viên thực hiện:
1. Mai Vũ Hà Mai – Msv: 20000566
2. Đoàn Lương Hiếu – Msv: 20000551
3. Nguyễn Kim Hiếu – Msv: 20000552
4. Nguyễn Công Đạt – Msv : 20000541

Hà Nội, 2022
------
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
1. Nhiều chuỗi truy vấn
- Nhiều chỗ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.
2. Ưu tiên của các mệnh đề
- Ưu tiên của các mệnh đề là việc tăng trọng số cho mệnh đề ta quan tâm
trong truy vấn bool bằng cách dùng tham số boost, mệnh đề được ưu tiên sẽ
đặt giá trị boost lớn hơn.
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": { (1)
"title": {
"query": "War and Peace",
"boost": 2
}}},
{ "match": { (1)
"author": {
"query": "Leo Tolstoy",
"boost": 2
}}},
{ "bool": { (2)
"should": [
{ "match": { "translator": "Constance Garnett" }},
{ "match": { "translator": "Louise Maude" }}
]
}}
]
}
}
}

- Giá trị boost “tốt nhất” nằm giữa 1 và 10, có khi là 15 các giá trị cao hơn
đem lại ít tác dụng hơn do số điểm được chuẩn hóa.
3. 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.
4. 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.
a. 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)
- }
- }
- }

b. 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 tườ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
c. 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.
5. 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.
6. 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ạ của trường:
PUT /my_index
{
"mappings": {
"person": {
"properties": {
"first_name": {
"type": "string",
"copy_to": "full_name" (1)
},
"last_name": {
"type": "string",
"copy_to": "full_name" (1)
},
"full_name": {
"type": "string"
}
}
}
}
}
1. Giá trị của trường first_name và last_name cũng được lưu vào trường
full_name.
Với ánh xạ ở đây, ta có thể truy vấn trường first_name cho các tên, trường
last_name cho các họ, hoặc trường full_name cho tên và họ
Việc ánh xạ các trường first_name và last_name không có tác dụng gì tới
cách mà trường full_name được đánh chỉ mục. Trường full_name sao lưu
giá trị xâu từ 2 trường còn lại, rồi đánh chỉ mục chúng chỉ theo như ánh xạ
của trường full_name
7. 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.
Để mô tả sự khác biệt giữa truy vấn tập trung vào trường và truy vấn tập trung vào
từ, hãy nhìn và explanation của truy vấn tập trung vào từ most_fields sau đây:
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "most_fields",
"operator": "and", (1)
"fields": [ "first_name", "last_name" ]
}
}
}
1. Mọi từ đều là bắt buộc phải có.
Để một tài liệu có thể ăn khớp, cả peter và smith đều phải xuất hiện trong cùng một
trường, hoặc là first_name hoặc là last_name:
(+first_name:peter +first_name:smith)

(+last_name:peter +last_name:smith)

Một phương pháp tiếp cận tập trung vào từ thì thay vào đó sẽ sử dụng logic như
sau:
+(first_name:peter last_name:peter)

+(first_name:smith last_name:smith)

Hay nói cách khác, từ peter phải xuất hiện ở ít nhất 1 trong 2 trường, và từ smith
cũng như vậy.

8. Ư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.
9. 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.
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title", "first_name", "last_name" ]
}
}
}
Vì trường title chưa được phân tích, nên nó chỉ tìm các trường bao gồm một từ
khóa là toàn bộ chuỗi truy vấn!
title:peter smith

blended("peter", fields: [first_name, last_name])

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

Từ khóa này rõ ràng là không tồn tại trong chỉ mục đảo ngược của trường title, và
sẽ không bao giờ có thể tìm ra được. Hãy tránh dùng các trường dạng
non_analyzed trong các truy vấn multi_match.

You might also like