2013-08-23 36 views
7

Tôi có chỉ mục vị trí, có nhiều tên vị trí và quốc gia tương ứng của chúng.Đối sánh chính xác với Tìm kiếm Đàn hồi (tại thời điểm truy vấn)

Sau đó tôi muốn biết liệu chúng tôi có vị trí có tiêu đề "Berlin" ở quốc gia có mã quốc gia "DE" hay không.

Dưới đây là nỗ lực mã Java của tôi:

SearchResponse response = client.prepareSearch("locations") 
       .setQuery(QueryBuilders.matchQuery("title", "Berlin")) 
       .setFilter(FilterBuilders.termFilter("country", "DE")) 
       .execute() 
       .actionGet(); 

Nhưng điều này mang lại cho tôi quá nhiều trả lời, ví dụ quả tìm kiếm cho "Zoo Berlin" và như vậy. Tôi cần các trận đấu chính xác.

(Nhưng xin lưu ý rằng tôi có kịch bản khác, nơi khớp chuỗi con/tìm kiếm văn bản này là mong muốn.)

Có cách nào để quyết định tại truy vấn thời gian, chứ không phải là lúc lập chỉ mục mà hành vi (chính xác so với phân tích văn bản) ai muốn?

+0

Kết hợp chính xác, ý của bạn là "berlin" phải khớp với "Berlin"? Ví dụ: – ramseykhalaf

+0

Có. (Và tôi không bận tâm quá nhiều về vụ việc ở đây.) Nhưng nếu "Berlin" phù hợp với "Berlin Hauptbahnhof", đó là vấn đề. –

Trả lời

10

Lập chỉ mục trường bạn thực hiện bộ lọc cụm từ khi không được đánh dấu. Ví dụ, bạn có thể chỉ mục các "quốc gia" lĩnh vực như một multi_field, với một trong những tiểu lĩnh vực not_analyzed:

 "country": { 
      "type": "multi_field", 
      "fields": { 
       "country": {"type": "string", "index": "analyzed"}, 
       "exact": {"type": "string","index": "not_analyzed"} 
      } 
     } 

Ngoài ra, bạn có thể làm tương tự với những "danh hiệu" lĩnh vực để thực hiện một thuật ngữ truy vấn:

 "title": { 
      "type": "multi_field", 
      "fields": { 
       "title": {"type": "string", "index": "analyzed"}, 
       "exact": {"type": "string","index": "not_analyzed"} 
      } 
     } 

Sau đó, vào thời điểm truy vấn, nếu bạn muốn có một tiêu đề với các thuật ngữ chính xác "Berlin" lọc bởi thuật ngữ chính xác "DE", sử dụng một truy vấn hạn và bộ lọc hạn với các trường not_analyzed:

SearchResponse response = client.prepareSearch("locations") 
       .setQuery(QueryBuilders.termQuery("title.exact", "Berlin")) 
       .setFilter(FilterBuilders.termFilter("country.exact", "DE")) 
       .execute() 
       .actionGet(); 

Lưu ý rằng term filtersterm queries yêu cầu các trường not_analyzed hoạt động (tức là, để trả lại kết quả khớp chính xác).

+2

Có cách nào để thực hiện truy vấn not_analyzed tại thời điểm truy vấn, mà không thay đổi ánh xạ? –

+0

Không chắc chắn.Bạn có thể sử dụng API cập nhật để thêm một trình phân tích vào chỉ mục của bạn và chỉ định trình phân tích đó tại thời điểm truy vấn. Xem [SO câu hỏi này] (http://stackoverflow.com/questions/11657505/defining-analyzer-while-querying-in-elasticsearch). Tuy nhiên, tôi không biết nếu bạn có thể chỉ định chỉ mục: not_analyzed mà không thay đổi ánh xạ. –

+0

Theo http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_finding_exact_values.html bản đồ phải được thay đổi ("Xoá chỉ mục đầu tiên là bắt buộc, vì chúng tôi không thể thay đổi ánh xạ đã tồn tại".) –

0

Với phiên bản 5 + trên ElasticSearch không có khái niệm phân tích và không được phân tích cho chỉ mục, được định hướng theo loại!

Loại dữ liệu chuỗi không được chấp nhận và được thay thế bằng văn bản và từ khóa, vì vậy nếu kiểu dữ liệu của bạn là văn bản, nó sẽ hoạt động như chuỗi và có thể được phân tích và mã thông báo.

Nhưng nếu loại dữ liệu được định nghĩa là từ khóa thì tự động KHÔNG được phân tích và trả về kết hợp chính xác hoàn toàn.

Vì vậy, bạn nên nhớ đánh dấu loại là từ khóa khi bạn muốn thực hiện đối sánh chính xác.

và bạn có thể sử dụng cùng một cụm từ truy vấn và thuật ngữ bộ lọc như được giải thích bởi @Scott Rice.

ví dụ mã dưới đây để tạo chỉ mục với định nghĩa này, lưu ý rằng tôi đã tạo hai loại cho mỗi trường như tokenizable do đó, văn bản và một loại khác chính xác, do đó, gõ là từ khóa, một số lần hữu ích để giữ cho cả hai trường :

PUT testindex 
{ 
    "mappings": { 
     "original": { 
     "properties": { 
      "@timestamp": { 
      "type": "date" 
      }, 
      "@version": { 
      "type": "text", 
      "fields": { 
       "keyword": { 
       "type": "keyword", 
       "ignore_above": 256 
       } 
      } 
      }, 
      "APPLICATION": { 
      "type": "text", 
      "fields": { 
       "token": {"type": "text"}, 
       "exact": {"type": "keyword"} 
      } 
      }, 
      "type": { 
      "type": "text", 
      "fields": { 
       "token": {"type": "text"}, 
       "exact": {"type": "keyword"} 
      } 
      } 
     } 
     } 
    } 
    } 
Các vấn đề liên quan