2014-07-02 19 views
11

Tôi đang cố gắng truy vấn thuộc tính lồng nhau với nhiều giá trị.Tìm kiếm trường lồng nhau cho nhiều giá trị trên cùng một trường với elasticsearch

Dưới đây là ví dụ sẽ rõ ràng hơn.

Tạo một chỉ mục với một lĩnh vực lồng nhau

curl -X DELETE "http://localhost:9200/testing_nested_query/" 
    curl -X POST "http://localhost:9200/testing_nested_query/" -d '{ 
     "mappings": { 
      "class": { 
       properties: { 
       title: {"type": "string"}, 
       "students": { 
        "type": "nested", 
        "properties": { 
        "name": {"type": "string"} 
        } 
       } 
       } 
      } 
     } 

    }' 

Thêm một số giá trị

curl -XPUT 'http://localhost:9200/testing_nested_query/class/1' -d '{ 
     "title": "class1", 
     "students": [{"name": "john"},{"name": "jack"},{"name": "jim"}] 
    }' 

    curl -XPUT 'http://localhost:9200/testing_nested_query/class/2' -d '{ 
     "title": "class2", 
     "students": [{"name": "john"},{"name": "chris"},{"name": "alex"}] 
    }' 

Query cho tất cả các lớp học nơi john là (2 hit như mong đợi)

curl -XGET 'http://localhost:9200/testing_nested_query/class/_search' -d '{ 
    "query": { 
    "nested": { 
     "path":"students", 
     "query": { 
     "bool": { 
      "must": [ 
      {"match": {"students.name": "john"}} 
      ] 
     } 
     } 
    } 
    } 
}' 

Query cho các lớp học mà cả hai john và jack đang theo học (0 kết quả thay vì 1)

curl -XGET 'http://localhost:9200/testing_nested_query/class/_search' -d '{ 
    "query": { 
    "nested": { 
     "path":"students", 
     "query": { 
     "bool": { 
      "must": [ 
      {"match": {"students.name": "john"}}, 
      {"match": {"students.name": "jack"}} 
      ] 
     } 
     } 
    } 
    } 
}' 

Tôi đã thử với trận đấu và lọc nhưng tôi không bao giờ có thể nhận được các truy vấn để trả lại giá trị mong đợi.

+0

Truy vấn sẽ làm việc chỉ đơn giản bằng cách sử dụng "nên" thay vì "phải". – plmaheu

+0

Không, với "nên" Nó trả về 2 lần truy cập thay vì một lần truy cập. –

+0

Bạn nói đúng, tôi đã đọc sai câu hỏi. – plmaheu

Trả lời

18

Nó chỉ cần một sự thay đổi chút:

{ 
    "query": { 
    "bool": { 
     "must": [ 
      { 
       "nested": { 
        "path":"students", 
        "query": { 
        "bool": { 
         "must": [ 
         {"match": {"name": "john"}} 
         ] 
        } 
        } 
       } 
      }, 
      { 
       "nested": { 
        "path":"students", 
        "query": { 
        "bool": { 
         "must": [ 
         {"match": {"name": "jack"}} 
         ] 
        } 
        } 
       } 
      } 
     ] 
    } 
    } 
} 

Tại sao?

Về cơ bản, trong truy vấn lồng nhau, truy vấn và bộ lọc được thực hiện chung trên một tài liệu lồng nhau - trong trường hợp một tên của bạn. Vì vậy, truy vấn của bạn sẽ nhận mọi tài liệu lồng nhau và cố gắng tìm mọi tài liệu có name bằng johnjack cùng một lúc - điều đó là không thể.

Truy vấn của tôi cố gắng tìm tài liệu được lập chỉ mục có một tài liệu lồng nhau với name bằng john và một tài liệu lồng nhau khác với name bằng jack. Vì vậy, về cơ bản một truy vấn lồng nhau cố gắng để phù hợp với một tài liệu lồng nhau hoàn toàn.

Để chứng minh những gì tôi gợi ý, hãy thử này:

Tạo chỉ số tương tự với cùng một bản đồ như bạn đã làm

** Sau đó, chỉ số các tài liệu sau **

curl -XPUT 'http://localhost:9200/testing_nested_query/class/1' -d '{ 
     "title": "class1", 
     "students": [{"name": "john", "age": 4},{"name": "jack", "age": 1},{"name": "jim", "age": 9}] 
    }' 

curl -XPUT 'http://localhost:9200/testing_nested_query/class/2' -d '{ 
     "title": "class1", 
     "students": [{"name": "john", "age": 5},{"name": "jack", "age": 4},{"name": "jim", "age": 9}] 
    }' 

Bây giờ, hãy thực hiện các truy vấn sau:

{ 
    "query": { 
     "nested": { 
      "path":"students", 
      "query": { 
      "bool": { 
       "must": [ 
       {"match": {"name": "john"}}, 
       {"match": {"age": 4}} 
       ] 
      } 
      } 
     } 
    } 
} 

Theo mong đợi của bạn, điều này phải khớp với 2 tài liệu nhưng nó thực sự chỉ phù hợp với một tài liệu. Vì chỉ có một tài liệu lồng nhau có cả hai name bằng johnage bằng 4.

Hy vọng điều đó sẽ hữu ích.

+0

Điều này hoạt động hoàn hảo. Cảm ơn lời giải thích. –

2

Bạn cũng có thể thực hiện theo cách sau.nơi mà bạn không cần phải lặp lại bool một lần nữa trong một khối lồng nhau, vì có một người duy nhất để phù hợp trong khối đó, bạn chỉ có thể làm trận đấu dài mà không bool

{ 
 
    "query": { 
 
    "bool": { 
 
     "must": [{ 
 
     "nested": { 
 
      "path": "students", 
 
      "query": { 
 
      { 
 
       "term": { 
 
       "name": "john" 
 
       } 
 
      } 
 
      } 
 
     } 
 
     }, { 
 
     "nested": { 
 
      "path": "students", 
 
      "query": { 
 
      { 
 
       "term": { 
 
       "name": "jack" 
 
       } 
 
      } 
 
      } 
 
     } 
 
     }] 
 
    } 
 
    } 
 
}

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