2013-05-20 4 views
1

Disons que j'ai indexé un objet qui ressemble à:Nested requête ElasticSearch en Java

{ 
    firstName: "Ben" 
    lastName: "McCann" 
    urls: [{ canonical: "http://www.benmccann.com" }] 
    emails: [{ canonical: "[email protected]" }] 
} 

Comment puis-je créer ensuite une recherche pour « Ben » ou « McCann » ou « [email protected] "?

SearchRequest request = new SearchRequest(INDEX) 
    .source(new SearchSourceBuilder().query(QueryBuilders.boolQuery() 
     .should(QueryBuilders.matchQuery("firstName", "Ben")) 
     .should(QueryBuilders.matchQuery("lastName", "McCann")) 
     .should(QueryBuilders.nestedQuery("emails", QueryBuilders.matchQuery("emails.canonical", "[email protected]"))))); 

Répondre

4

Vous devez utiliser un nested query que si vous avez configuré le champ des e-mails comme nested type dans votre cartographie. Je ne pense pas que cela ait du sens dans votre cas puisque vous avez un sous-champ unique sous e-mails, appelés canoniques. Vous pouvez simplement utiliser à nouveau une requête de correspondance et la notation par points, en vous référant au champ emails.canonical.

Si vous utilisez une requête boolére, n'oubliez pas de mettre au minimum la correspondance qui doit correspondre, ce qui vous indique le nombre de clauses should qui doivent correspondre au moins à celles fournies dans la requête. Dans votre cas, ça devrait aller.

SearchRequest request = Requests.searchRequest(INDEX) 
    .source(SearchSourceBuilder.searchSource().query(QueryBuilders.boolQuery() 
     .should(QueryBuilders.matchQuery("firstName", "Ben")) 
     .should(QueryBuilders.matchQuery("lastName", "McCann")) 
     .should(QueryBuilders.matchQuery("emails.canonical", "[email protected]")) 
     .minimumShouldMatch(1))); 

D'autre part, si vous avez fait configurer le champ emails comme niché dans votre cartographie, vous devez utiliser une requête imbriquée. Je ne vois rien de mal dans ce que vous faites, vous manquez juste le minimum devrait correspondre au paramètre.