2014-04-02 13 views
11

Các bộ lọc của tôi được nhóm lại với nhau thành các danh mục. Tôi muốn truy xuất tài liệu trong đó tài liệu có thể khớp với bất kỳ bộ lọc nào trong một danh mục, nhưng nếu hai (hoặc nhiều) danh mục được đặt thì tài liệu phải khớp với bất kỳ bộ lọc nào trong TẤT CẢ các loại.Làm cách nào để thực hiện các bộ lọc lồng nhau AND và OR trong Tìm kiếm Đàn hồi?

Nếu viết bằng pseudo-SQL nó sẽ là:

SELECT * FROM Documents WHERE (CategoryA = 'A') AND (CategoryB = 'B' OR CategoryB = 'C') 

Tôi đã thử các bộ lọc lồng nhau như vậy:

{ 
    "sort": [{ 
     "orderDate": "desc" 
    }], 
    "size": 25, 
    "query": { 
     "match_all": {} 
    }, 
    "filter": { 
     "and": [{ 
      "nested": { 
       "path":"hits._source", 
       "filter": { 
        "or": [{ 
         "term": { 
          "progress": "incomplete" 
         } 
        }, { 
         "term": { 
          "progress": "completed" 
         } 
        }] 
       } 
      } 
     }, { 
      "nested": { 
       "path":"hits._source", 
       "filter": { 
        "or": [{ 
         "term": { 
          "paid": "yes" 
         } 
        }, { 
         "term": { 
          "paid": "no" 
         } 
        }] 
       } 
      } 
     }] 
    } 
} 

Nhưng rõ ràng là tôi không hoàn toàn hiểu được cú pháp ES. Điều này có đúng hay tôi cần sử dụng một bộ lọc khác?

+0

không phải là câu trả lời cho câu hỏi: '' hoặc'' với '' term'' có thể được thực hiện dễ dàng hơn với [terms] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms- filter.html). và mặc định cho [bool] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html) là '' và''. một cái gì đó dọc theo '' filter.bool.must: [{terms: progress: ["not complete", "complete"]}. {terms: paid: ["yes", "no"]}] '' có thể hoạt động? – cfrick

+0

truy vấn lồng nhau/bộ lọc được sử dụng cho mảng/danh sách (phụ thuộc vào ngôn ngữ bạn quen thuộc với ví dụ: 'a = [{'b': 1}, {'c': 2}])'. Bạn có thể viết một ví dụ về một trong các tài liệu của bạn không? Điều đó sẽ giúp – Diolor

+0

cfrick đã dẫn tôi đi đúng hướng. Tôi lồng nhau một loạt các bộ lọc 'điều khoản' bên trong một bộ lọc 'và', và nó dường như đáp ứng nhu cầu của tôi. – MHTri

Trả lời

3

Mặc dù tôi chưa hiểu hoàn toàn cấu trúc của bạn nhưng đây có thể là những gì bạn cần.

Bạn phải suy nghĩ một cách khôn ngoan. Bạn tạo một bool mà bạn phải (= và) thực hiện các bool nhúng. Mỗi kiểm tra nhúng nếu trường không tồn tại hoặc người nào khác (sử dụng nên ở đây thay vì phải) lĩnh vực phải (điều khoản ở đây) là một trong những giá trị trong danh sách.

Không chắc chắn nếu có cách nào tốt hơn và không biết hiệu suất.

{ 
    "sort": [ 
     { 
      "orderDate": "desc" 
     } 
    ], 
    "size": 25, 
    "query": { 
     "query": {   # 
      "match_all": {} # These three lines are not necessary 
     },     # 
     "filtered": { 
      "filter": { 
       "bool": { 
        "must": [ 
         { 
          "bool": { 
           "should": [ 
            { 
             "not": { 
              "exists": { 
               "field": "progress" 
              } 
             } 
            }, 
            { 
             "terms": { 
              "progress": [ 
               "incomplete", 
               "complete" 
              ] 
             } 
            } 
           ] 
          } 
         }, 
         { 
          "bool": { 
           "should": [ 
            { 
             "not": { 
              "exists": { 
               "field": "paid" 
              } 
             } 
            }, 
            { 
             "terms": { 
              "paid": [ 
               "yes", 
               "no" 
              ] 
             } 
            } 
           ] 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
} 
+2

Điều này không đúng. 'must' và' should' không phải là bí danh cho 'và' và' hoặc'. Họ có chức năng khác nhau (mặc dù có những điểm tương đồng về khái niệm) –

8

này nên được nó (dịch từ trao pseudo-SQL)

{ 
    "sort": [ 
     { 
     "orderDate": "desc" 
     } 
    ], 
    "size": 25, 
    "query": 
    { 
     "filtered": 
     { 
      "filter": 
      { 
       "and": 
       [ 
        { "term": { "CategoryA":"A" } }, 
        { 
         "or": 
         [ 
          { "term": { "CategoryB":"B" } }, 
          { "term": { "CategoryB":"C" } } 
         ] 
        } 
       ] 
      } 
     } 
    } 
} 

Tôi nhận ra bạn không nhắc đến khía cạnh nhưng chỉ vì lợi ích của sự hoàn chỉnh:

Bạn cũng có thể sử dụng a filter làm cơ sở (giống như bạn đã làm) thay vì một số filtered query (như tôi đã làm). Các json kết quả là gần như giống hệt với sự khác biệt hạnh phúc:

  • một truy vấn lọc sẽ lọc tất cả các kết quả chính cũng như các khía cạnh
  • một bộ lọc sẽ chỉ lọc các kết quả chính NOT các khía cạnh.

Cuối cùng, bộ lọc lồng nhau (mà bạn đã cố gắng sử dụng) không liên quan đến 'bộ lọc làm tổ' như bạn có vẻ tin tưởng, nhưng liên quan đến lọc trên lồng nhau-văn (cha-con)

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