2014-08-28 15 views
6

Tôi có vài tài liệu json với định dạng sau: -OR và AND nhà khai thác trong Elasticsearch truy vấn

_source: { 
      userId: "A1A1", 
      customerId: "C1", 
      component: "comp_1", 
      timestamp: 1408986553, 
    } 

tôi muốn truy vấn các tài liệu dựa trên những điều sau đây: -

((userId == currentUserId) OR (customerId== currentCustomerId) OR (currentRole ==ADMIN)) AND component= currentComponent) 

tôi đã cố gắng sử dụng SearchSourceBuilder và QueryBuilders.matchQuery, nhưng tôi không thể đặt nhiều truy vấn phụ với toán tử AND và OR.

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
searchSourceBuilder.query(QueryBuilders.matchQuery("userId",userId)).sort("timestamp", SortOrder.DESC).size(count); 

Chúng tôi truy vấn elasticsearch bằng cách sử dụng toán tử OR và AND như thế nào?

Trả lời

24

Tôi nghĩ trong trường hợp này, Bool query là ảnh đẹp nhất.

Cái gì như:

{ 
    "bool" : { 
     "must" : { "term" : { "component" : "comp_1" } }, 
     "should" : [ 
      { "term" : { "userId" : "A1A1" } }, 
      { "term" : { "customerId" : "C1" } }, 
      { "term" : { "currentRole" : "ADMIN" } } 
     ], 
     "minimum_should_match" : 1 
    } 
} 

Mà cho trong Java:

QueryBuilder qb = QueryBuilders 
    .boolQuery() 
    .must(termQuery("component", currentComponent)) 
    .should(termQuery("userId", currentUserId)) 
    .should(termQuery("customerId", currentCustomerId)) 
    .should(termQuery("currentRole", ADMIN)) 
    .minimumShouldMatch("1"); // or .minimumNumberShouldMatch(1) 

Các must phần là AND s, should phần nhiều hay ít OR s, ngoại trừ việc bạn có thể chỉ định tối thiểu số lượng should s để khớp (sử dụng minimum_should_match), tối thiểu là 1 theo mặc định tôi nghĩ (nhưng bạn có thể đặt thành 0, nghĩa là tài liệu khớp với sốĐiều kiệncũng sẽ được trả lại).

Nếu bạn muốn thực hiện các truy vấn phức tạp hơn liên quan đến lồng nhau AND s và OR s, chỉ cần lồng các truy vấn bool khác trong các phần must hoặc should.

Ngoài ra, khi bạn đang tìm kiếm các giá trị chính xác (id và vv), có thể bạn sử dụng term queries instead of match queries, phụ tùng cho bạn giai đoạn phân tích (nếu các trường đó được phân tích, không nhất thiết phải có ý nghĩa đối với id). Nếu chúng được phân tích, bạn vẫn có thể làm điều đó, nhưng chỉ khi bạn biết chính xác cách các điều khoản của bạn được lưu trữ (standard analyzer stores them lower cased for instance).

+0

'.minimumShouldMatch' lấy chuỗi chỉ làm đối số, phải không? – BairDev

+0

@malte Bạn nói đúng. Trong trường hợp này, nó phải là 'minimumNumberShouldMatch' với một' int', hoặc 'minimumShouldMatch' với một' chuỗi'. Đã sửa. –

+0

Tôi nghĩ rằng đây phải là câu trả lời được chấp nhận. +1 – NickGreen

2

Nếu bạn sử dụng query_string query, AND và OR của bạn sẽ được giải thích như vậy bởi thư viện Lucene.

này cho phép bạn tìm kiếm

(currentUserId OR currentCustomerId) AND currentComponent 

ví dụ. Theo mặc định, các giá trị sẽ được tìm kiếm trong tất cả các trường.

+0

Nhưng một cái gì đó như 'QueryBuilders.queryString (" (userId: "+ currentUserId +" OR customerId: "+ currentCustomerId +" OR currentRole: "+ ADMIN +") VÀ thành phần: "+ currentComponent +") ")' nên làm việc theo cách dự định . –

+0

từ trang được liên kết của tài liệu Tìm kiếm Đàn hồi: "Trường mặc định cho cụm từ truy vấn nếu không có trường tiền tố nào được chỉ định. Mặc định là thiết lập chỉ mục index.query.default_field, lần lượt mặc định là _all." Rõ ràng, ElasticSearch thêm trường _all vào thời gian chỉ mục, sau đó chúng ta có thể áp dụng cú pháp Lucene. –

Các vấn đề liên quan