2014-07-02 15 views
11

Próbuję wysłać zapytanie do zagnieżdżonych właściwości z wieloma wartościami.Wyszukaj zagnieżdżone pole dla wielu wartości w tym samym polu za pomocą elasticsearch

Oto przykład, który będzie bardziej przejrzysty.

Tworzenie indeksu z zagnieżdżonego pola

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"} 
        } 
       } 
       } 
      } 
     } 

    }' 

Dodaj niektóre wartości

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 dla wszystkich klas, gdzie John (2 hity jak oczekiwano)

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

zapytań dla klas, w których zarówno John i Jack są uczestniczę (0 wyniki zamiast 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"}} 
      ] 
     } 
     } 
    } 
    } 
}' 

Próbowałem z meczu i filtrem, ale nigdy nie może dostać zapytanie do powrotu oczekiwanych wartości.

+0

Kwerenda będzie działać po prostu używając "powinien" zamiast "musi". – plmaheu

+0

Nie, z "should" Zwraca dwa trafienia zamiast jednego. –

+0

Masz rację, źle odczytałem pytanie. – plmaheu

Odpowiedz

18

To po prostu potrzebuje zmiany bitowe:

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

Dlaczego?

Zasadniczo w zapytaniu zagnieżdżonym zapytanie i filtr są wspólnie wykonywane w pojedynczym dokumencie zagnieżdżonym - w Twoim przypadku to jedno imię. W związku z tym zapytanie będzie pobierać każdy zagnieżdżony dokument i spróbować znaleźć każdy dokument, który ma name równy john i jack w tym samym czasie - co jest niemożliwe.

Moje zapytanie próbuje znaleźć indeksowanego dokumentu, który ma jeden dokument z zagnieżdżonego name równej john i inny dokument zagnieżdżonego z name równą jack. Zatem zasadniczo jedno zagnieżdżone zapytanie próbuje całkowicie dopasować jeden zagnieżdżony dokument.

Aby udowodnić to, co ja sugeruję, spróbuj tego:

utworzyć ten sam indeks z samego mapowania jak ty

** Następnie indeks następujące dokumenty **

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}] 
    }' 

Teraz wykonaj następujące zapytania:

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

Zgodnie z twoimi oczekiwaniami, powinno to odpowiadać 2 dokumentom, ale faktycznie pasuje tylko do jednego. Ponieważ istnieje tylko jeden zagnieżdżony dokument, który ma zarówno name równy john i age równy 4.

Nadzieję, że pomaga.

+0

To działa idealnie. Dziękuję za wyjaśnienie. –

2

Można również wykonać następujące czynności.gdzie nie trzeba powtarzać Bool ponownie w zagnieżdżonego bloku, ponieważ nie jest jedynym, który pasuje w tym bloku, można po prostu zrobić perspektywie mecz bez bool

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

Powiązane problemy