2013-05-10 38 views
9

Tôi mới sử dụng ElasticSearch và Couchbase. Tôi đang xây dựng một ứng dụng Java mẫu để tìm hiểu thêm về ElasticSearch và Couchbase.Tìm kiếm đàn hồi - Sử dụng bộ lọcBuilder

Đọc ElasticSearch Java API, Bộ lọc được sử dụng tốt hơn trong trường hợp sắp xếp theo điểm không cần thiết và để lưu vào bộ nhớ cache. tôi vẫn chưa tìm ra cách để sử dụng FilterBuilders và có thắc mắc sau:

  • thể FilterBuilders được sử dụng một mình để tìm kiếm?
  • Hoặc chúng luôn phải được sử dụng với một số Query? (Nếu đúng, có thể ai đó vui lòng liệt kê một ví dụ không?)
  • Đi qua tài liệu, nếu tôi muốn thực hiện tìm kiếm dựa trên giá trị trường và muốn sử dụng Trình tạo bộ lọc, làm cách nào tôi có thể thực hiện điều đó? (Sử dụng AndFilterBuilder hoặc TermFilterBuilder hoặc InFilterBuilder? Tôi không rõ ràng về sự khác biệt giữa chúng.)

Đối với câu hỏi thứ 3, tôi thực sự đã thử nghiệm nó với tìm kiếm sử dụng các truy vấn và sử dụng bộ lọc như hình dưới đây. Tôi nhận được kết quả trống (không có hàng) khi tôi thử tìm kiếm bằng cách sử dụng FilterBuilders. Tôi không chắc mình đang làm gì sai.

Bất kỳ ví dụ nào đều hữu ích. Tôi đã có một thời gian khó khăn đi qua tài liệu mà tôi tìm thấy thưa thớt và thậm chí tìm kiếm dẫn đến các diễn đàn người dùng không đáng tin cậy khác nhau.

private void processQuery() { 
     SearchRequestBuilder srb = getSearchRequestBuilder(BUCKET); 
     QueryBuilder qb = QueryBuilders.fieldQuery("doc.address.state", "TX"); 
     srb.setQuery(qb); 

     SearchResponse resp = srb.execute().actionGet(); 
     System.out.println("response :" + resp); 
    } 

private void searchWithFilters(){ 
     SearchRequestBuilder srb = getSearchRequestBuilder(BUCKET); 
     srb.setFilter(FilterBuilders.termFilter("doc.address.state", "tx")); 
     //AndFilterBuilder andFb = FilterBuilders.andFilter(); 
     //andFb.add(FilterBuilders.termFilter("doc.address.state", "TX")); 
     //srb.setFilter(andFb); 
     SearchResponse resp = srb.execute().actionGet(); 
     System.out.println("response :" + resp); 
    } 

- -UPDATE--

Như đã đề cập trong câu trả lời, thay đổi thành chữ thường "tx" công trình. Với câu hỏi này được giải quyết. Tôi vẫn có các câu hỏi sau:

  • Trong trường hợp nào, là bộ lọc được sử dụng với truy vấn? Mục đích của mục đích này là gì?
  • Sự khác biệt giữa InFilter, TermFilterMatchAllFilter. Mọi hình minh họa sẽ giúp ích.

Trả lời

11

Phải, bạn nên sử dụng bộ lọc để loại trừ các tài liệu thậm chí không được xem xét khi thực hiện truy vấn. Bộ lọc nhanh hơn vì chúng không liên quan đến bất kỳ điểm nào và cũng có thể lưu vào bộ nhớ cache.

Điều đó nói rằng, rõ ràng là bạn phải sử dụng bộ lọc với search api, thực hiện truy vấn và chấp nhận bộ lọc tùy chọn. Nếu bạn chỉ có bộ lọc, bạn chỉ có thể sử dụng truy vấn match_all cùng với bộ lọc của mình. Một bộ lọc có thể là một bộ lọc đơn giản hoặc một bộ lọc để kết hợp nhiều bộ lọc với nhau.

Về số Java API, tên được sử dụng là tên của các bộ lọc có sẵn, không có sự khác biệt lớn. Hãy xem số this search example chẳng hạn. Trong mã của bạn, tôi không thấy nơi bạn làm setFilter trên đối tượng SearchRequestBuilder của bạn. Có vẻ như bạn không cần bộ lọc và vì bạn đang sử dụng một bộ lọc duy nhất. Hơn nữa, có thể bạn đang lập chỉ mục bằng ánh xạ mặc định, do đó thuật ngữ "TX" được hạ thấp. Đó là lý do tại sao khi bạn tìm kiếm bằng bộ lọc cụm từ bạn không tìm thấy bất kỳ kết quả phù hợp nào. Hãy thử tìm kiếm "tx" thấp hơn.

Bạn có thể thay đổi ánh xạ nếu muốn giữ cụm từ "TX" giống như trong khi lập chỉ mục, có thể đặt trường là not_analyzed nếu nó chỉ là một mã thông báo duy nhất. Nếu không, bạn có thể thay đổi bộ lọc, bạn có thể muốn xem xét truy vấn được phân tích để truy vấn của bạn được phân tích giống như cách nội dung được lập chỉ mục.

Có một cái nhìn tại query DSL documentation để biết thêm thông tin về truy vấn và bộ lọc:

  • MatchAllFilter: trận đấu tất cả các tài liệu của bạn, không phải là hữu ích tôi muốn nói
  • TermFilter: Bộ lọc tài liệu mà có các trường có chứa một thuật ngữ (không được phân tích)
  • AndFilter: lọc hợp chất sử dụng để đưa vào và thêm hai hoặc bộ lọc

Không biết ý của bạn là gì bởi InFilterBuilder, không thể tìm thấy bất kỳ bộ lọc nào có tên này.

Truy vấn thường chứa những gì người dùng nhập vào thông qua hộp tìm kiếm văn bản. Bộ lọc có nhiều cách để tinh chỉnh tìm kiếm, ví dụ như nhấp vào các mục nhập khía cạnh. Đó là lý do tại sao bạn vẫn sẽ có truy vấn cộng với một hoặc nhiều bộ lọc.

+0

Bạn nói đúng, tôi chỉnh sửa bài để thiết lập bộ lọc trên searchrequestbuilder. và bằng cách thay đổi thành "tx" tôi thấy kết quả! cảm ơn. Tôi đã chỉnh sửa bài viết để bao gồm điều này và một số câu hỏi vẫn còn tồn tại..thanks một lần nữa. –

+0

Tôi đã cập nhật câu trả lời của mình theo câu hỏi được cập nhật của bạn, hãy xem nó. – javanna

+0

Hãy xem ví dụ tìm kiếm này cho ví dụ liên kết bị hỏng. –

6

Để thêm những gì @javanna nói:

Rất nhiều sự nhầm lẫn có thể xuất phát từ thực tế là bộ lọc có thể được định nghĩa theo nhiều cách:

Sự khác biệt bạn có thể hỏi là gì. Và thực sự bạn có thể xây dựng chính xác cùng một logic theo cả hai cách.

Sự khác biệt là truy vấn hoạt động trên cả hai kết quả cũng như bất kỳ khía cạnh nào bạn đã xác định. Trong khi đó, một Bộ lọc (khi được định nghĩa độc lập) chỉ hoạt động trên resultset và KHÔNG trên bất kỳ khía cạnh nào bạn đã xác định (được giải thích tại đây: http://www.elasticsearch.org/guide/reference/api/search/filter/)

2

Để thêm vào các câu trả lời khác, Bộ lọc chỉ được sử dụng với Bộ lọc. Định nghĩa là, InFilter: Bộ lọc cho một trường dựa trên một số cụm từ khớp với bất kỳ từ nào trong số chúng.

API truy vấn Java sử dụng trình tạo bộ lọc, là một nhà máy cho trình tạo bộ lọc có thể tự động tạo truy vấn từ mã Java. Chúng tôi thực hiện việc này bằng cách sử dụng biểu mẫu và chúng tôi xây dựng truy vấn của chúng tôi dựa trên các lựa chọn của người dùng từ đó với các hộp kiểm, tùy chọn và menu thả xuống.

Dưới đây là một số Example code for FilterBuilders và có một đoạn từ liên kết đó có sử dụng InFilter như hình dưới đây:

FilterBuilder filterBuilder; 
    User user = (User) auth.getPrincipal(); 
    if (user.getGroups() != null && !user.getGroups().isEmpty()) { 
     filterBuilder = FilterBuilders.boolFilter() 
       .should(FilterBuilders.nestedFilter("userRoles", FilterBuilders.termFilter("userRoles.key", auth.getName()))) 
       .should(FilterBuilders.nestedFilter("groupRoles", FilterBuilders.inFilter("groupRoles.key", user.getGroups().toArray()))); 
    } else { 
     filterBuilder = FilterBuilders.nestedFilter("userRoles", FilterBuilders.termFilter("userRoles.key", auth.getName())); 
    } 
    ... 
Các vấn đề liên quan