2014-05-12 15 views
21

Tôi hơi bối rối khi tạo truy vấn được lọc trong API Java của Elasticsearch. Lớp SearchRequestBuilder có phương thức setPostFilter, javadoc của phương thức này nói rõ ràng rằng bộ lọc sẽ được áp dụng sau khi Query được thực thi.Truy vấn được lọc trong API Java của Elasticsearch

Tuy nhiên, không có phương pháp setFilter Hoặc một số phương pháp khác sẽ cho phép áp dụng bộ lọc trước khi thực hiện truy vấn
. Làm cách nào để tạo Query được lọc (về cơ bản áp dụng bộ lọc trước khi truy vấn được thực hiện) ở đây? Tui bỏ lỡ điều gì vậy?

Trả lời

28
FilteredQueryBuilder builder = 
QueryBuilders.filteredQuery(QueryBuilders.termQuery("test", 
"test"),FilterBuilders.termFilter("test","test")); 

Nó sẽ tạo truy vấn được lọc ... Để lọcTruy vấn, tham số đầu tiên là truy vấn và đối số thứ hai là Bộ lọc.

Cập nhật: Truy vấn được lọc bị khấu hao trong elasticsearch 2.0+. refer

Hy vọng nó sẽ giúp ..!

+0

mọi thứ đã thay đổi trong API phiên bản 2.0 trở lên. Xem câu trả lời của tôi. – daphshez

+0

cảm ơn bạn đã cập nhật @DaphnaShezaf. – BlackPOP

8

Trong trường hợp bạn chỉ muốn thực hiện bộ lọc mà không cần truy vấn, bạn có thể làm như thế này:

FilteredQueryBuilder builder = QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), 
    FilterBuilders.termFilter("username","stackoverflow")); 

Ref:. Filtering without a query

+0

Cảm ơn, câu trả lời rất hữu ích;) – Sapikelio

7

QueryBuilders.filteredQuery bị phản đối trong API v 2.0.0 và sau đó.

Thay vào đó, bộ lọc và truy vấn có "quyền bình đẳng". FilterBuilders không còn tồn tại và tất cả các bộ lọc được tạo bằng cách sử dụng QueryBuilders.

Để thực hiện các truy vấn với bộ lọc duy nhất (trong trường hợp này, geo lọc), bây giờ bạn sẽ làm gì:

QueryBuilder query = QueryBuilders.geoDistanceQuery("location") 
     .point(center.getLatitude(), center.getLongitude()) 
     .distance(radius, DistanceUnit.METERS); 

// and then... 
SearchResponse resp = client.prepareSearch(index).setQuery(query); 

Nếu bạn muốn truy vấn bởi hai nhiệm kỳ, bạn sẽ cần phải sử dụng boolQuery với must:

QueryBuilder query = QueryBuilders.boolQuery() 
      .must(QueryBuilders.termQuery("user", "ben")) 
      .must(QueryBuilders.termQuery("rank", "mega")); 

// and then... 
SearchResponse resp = client.prepareSearch(index).setQuery(query); 
+0

theo [tài liệu] (https://www.elastic.co/guide/en/elasticsearch/guide/current/_queries_and_filters.html) có sự khác biệt giữa ngữ cảnh truy vấn và bộ lọc , cụ thể là lọc không có điểm số của các trận đấu và có thể hoạt động tốt hơn. Daphna, khi sử dụng API như được đề xuất, điều này có thể đạt được sự khác biệt đạt được hay được tính toán một cách ngầm định (do đó có khả năng lấy đi hiệu suất)? –

+0

@ YonatanWilkof Đó là một câu hỏi hay. Bạn nên hỏi nó như là một câu hỏi chính chứ không phải trong chuỗi ý kiến, ai đó có thể giúp bạn. – daphshez

+0

Có vẻ như bằng cách gói truy vấn (một đối tượng BoolQueryBuilder) bằng cách cho nó như một đối số cho boolQuery(). Filter (..) và sau đó thiết lập trong setQuery() như bạn đã đề xuất, thì điều này có thể đạt được. Khóa "điểm" trong phản hồi luôn là 0 (mặc dù tài liệu được tìm thấy) –

1

dường như bằng cách gói truy vấn (một đối tượng BoolQueryBuilder) bằng cách cho nó như một cuộc tranh cãi để boolQuery(). lọc (..) và sau đó thiết lập rằng trong setQuery() như bạn suggested- thì điều này có thể đạt được. Khóa "điểm" trong phản hồi luôn là 0 (mặc dù tài liệu được tìm thấy)

Hãy cẩn thận ở đây! Nếu điểm số là 0, điểm số đã được tính. Điều đó có nghĩa là truy vấn vẫn còn trong ngữ cảnh truy vấn chứ không phải trong ngữ cảnh bộ lọc. Trong bối cảnh bộ lọc, điểm số được đặt thành 1.0 (không tính toán) source

Để tạo truy vấn trong ngữ cảnh bộ lọc mà không tính điểm (điểm = 1.0) thực hiện như sau (Có thể vẫn còn cách tốt hơn?):

QueryBuilder qb = QueryBuilders.constantScoreQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name", "blub))); 

này trả về kết quả tương tự như:

GET /indexName/typeName/_search 
    { 
     "filter": { 
     "query": { 
      "bool": { 
      "must": [ 
       { "match": { 
       "name": "blub" 
       }} 
      ] 
      } 
     } 
     } 
    } 
0

Kể từ FilteredQueryBuilder bị phản đối trong các phiên bản gần đây, người ta có thể sử dụng QueryBuilders.boolQuery() thay vào đó, với một điều khoản bắt buộc đối với các truy vấn và một điều khoản lọc cho f ilter.

import static org.elasticsearch.index.query.QueryBuilders.*; 

QueryBuilder builder = boolQuery().must(termQuery("test", "test")).filter( boolQuery().must(termQuery("test", "test"))); 
Các vấn đề liên quan