Thực hiện tìm kiếm văn bản chính xác trong Elaticsearch hơi phức tạp. Một trong những cách được đề xuất để tìm kiếm một trường cho văn bản là sử dụng truy vấn đối sánh như được hiển thị bên dưới [tìm kiếm “Châu Phi”]
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"Area": "africa"
}
}
]
}
},
"from": 0,
"size": 25
}
Tìm kiếm này tìm thấy kết quả phù hợp cho "Châu Phi" như mong đợi. Tuy nhiên, nó cũng tìm thấy những trận đấu này
...
{
"Element Code": 7231,
"Area": "Eastern Africa",
"Value": 29633.4361
},
{
"Element Code": 7231,
"Area": "Eastern Africa",
"Value": 32236.7717
},
...
...
{
"Element Code": 7231,
"Area": "Western Africa",
"Value": 90869.5537
},
{
"Element Code": 7231,
"Area": "Western Africa",
"Value": 97677.0082
},
...
...
{
"Element Code": 7231,
"Area": "Southern Africa",
"Value": 239990.2601
},
{
"Element Code": 7231,
"Area": "Southern Africa",
"Value": 234594.409
},
...
Không phải là một tình huống tốt khi bạn chỉ tìm kiếm chính xác “Châu Phi”, phải không?
Lý do điều này xảy ra là do truy vấn so khớp phân tích văn bản trước khi thực hiện tìm kiếm. Điều này có nghĩa là văn bản được chuyển đổi thành mã thông báo [hoặc thuật ngữ], chữ thường mã thông báo [đối với bộ phân tích tiếng Anh] và áp dụng các phép biến đổi như loại bỏ các từ dừng thường xuyên và giảm mã thông báo thành gốc từ của chúng [e. g. cáo -> cáo, nhảy -> nhảy, v.v.]. Tùy thuộc vào cách tài liệu được lập chỉ mục, tìm kiếm có thể tìm thấy hoặc không tìm thấy tài liệu của bạn
Sử dụng một Term Query
Một giải pháp cho việc thực hiện tìm kiếm văn bản chính xác này là sử dụng truy vấn thuật ngữ
Nhưng lưu ý cảnh báo trên trang truy vấn thuật ngữ không sử dụng truy vấn thuật ngữ để tìm kiếm văn bản. Những gì chúng tôi sẽ làm là thực hiện tìm kiếm từ khóa trên trường [hậu tố “. từ khóa” được đính kèm với tên trường]
{
"query": {
"bool": {
"must": [
{
"term": {
"Area.keyword": "Africa"
}
}
]
}
},
"from": 0,
"size": 25
}
Kiểm tra ánh xạ
Tất nhiên, điều này phụ thuộc vào cách tài liệu đã được lập chỉ mục. Nếu bạn đã sử dụng ánh xạ động, điều đó có nghĩa là dữ liệu chuỗi sẽ được lưu trữ dưới dạng toàn văn cũng như từ khóa để cho phép cả hai loại tìm kiếm. Bạn có thể kiểm tra loại ánh xạ cho trường là gì
curl -X GET "localhost:9200/emissions/_mapping?pretty"
hiển thị loại ánh xạ cho trường quan tâm Khu vực. Trường được lưu trữ dưới dạng văn bản và từ khóa với các ký tự trên 256 bị bỏ qua
{
...
"Area" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
...
}
Và khi chúng tôi thực hiện truy vấn thuật ngữ với trường là từ khóa, chúng tôi nhận được kết quả phù hợp chính xác mà chúng tôi đang tìm kiếm - chỉ Châu Phi và không có gì khác
Chúng tôi đang di chuyển chiến lược tìm kiếm của mình, từ cơ sở dữ liệu sang Tìm kiếm đàn hồi. Trong thời gian này, chúng tôi cần duy trì chức năng hiện có của việc tìm kiếm một phần trường tương tự như truy vấn SQL bên dưới [bao gồm cả khoảng trắng]
LỰA CHỌN *
TỪ khách hàng
Ở ĐÂU customer_id THÍCH '%0995%';
Phải nói rằng, tôi đã xem qua nhiều bài viết liên quan đến ES và đạt được chức năng nói trên. Sau bài tập trên, sau đây là những gì tôi nghĩ ra
- Phần lớn các bài báo mà tôi đã đọc khuyến nghị sử dụng bộ phân tích/bộ lọc nGram;
Ghi chú. Độ dài tối đa của trường customer_id là VARCHAR2[100]
{
"customer-index":{
"aliases":{
},
"mappings":{
"customer":{
"properties":{
"customerName":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
},
"customerId":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
},
"analyzer":"substring_analyzer"
}
}
}
},
"settings":{
"index":{
"number_of_shards":"3",
"provided_name":"customer-index",
"creation_date":"1573333835055",
"analysis":{
"filter":{
"substring":{
"type":"ngram",
"min_gram":"3",
"max_gram":"100"
}
},
"analyzer":{
"substring_analyzer":{
"filter":[
"lowercase",
"substring"
],
"type":"custom",
"tokenizer":"standard"
}
}
},
"number_of_replicas":"1",
"uuid":"XXXXXXXXXXXXXXXXX",
"version":{
"created":"5061699"
}
}
}
}
}
Yêu cầu truy vấn dữ liệu trông như thế này
________số 8_______Như đã nói, đây là một số truy vấn/vấn đề
- Giả sử có 3 bản ghi với customer_id
0009950011214, 0009900011214, 0009920011214
Khi tôi tìm kiếm "0995". Lý tưởng nhất là tôi chỉ mong nhận được customer_id. 0009950011214
Nhưng tôi nhận được cả ba bản ghi như một phần của tập hợp kết quả và tôi tin rằng đó là do bộ phân tích nGram và cách nó phân tách chuỗi [lưu ý. tối thiểuGram. 3 và maxGram. 100]. Đặt maxGram thành 100 là đối sánh chính xác