web-dev-qa-db-fra.com

OR et opérateurs AND dans la requête Elasticsearch

J'ai quelques documents json au format suivant: -

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

Je souhaite interroger le document sur la base des éléments suivants: -

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

J'ai essayé d'utiliser SearchSourceBuilder et QueryBuilders.matchQuery, mais je n'ai pas pu mettre plusieurs sous-requêtes avec AND et OR opérateurs.

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

Comment interroger elasticsearch en utilisant les opérateurs OR et AND?

15
Udit Bhatia

Je pense que dans ce cas, le requête Bool est le meilleur coup.

Quelque chose comme :

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

Ce qui donne en Java:

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

Les parties must sont ANDs, les parties should sont plus ou moins ORs, sauf que vous pouvez spécifier un nombre minimum de shoulds pour correspondre (en utilisant minimum_should_match), ce minimum étant 1 par défaut je pense (mais vous pouvez le mettre à 0, ce qui signifie qu'un document ne correspondant à aucune condition should serait également renvoyé).

Si vous souhaitez effectuer des requêtes plus complexes impliquant des ANDs et ORs imbriquées, imbriquez simplement d'autres requêtes booléennes dans les parties must ou should.

En outre, lorsque vous recherchez des valeurs exactes (identifiants, etc.), vous pouvez peut-être utiliser requêtes de terme au lieu de requêtes de correspondance , ce qui vous épargne la phase d'analyse (si ces champs sont analysés, ce qui n'a pas nécessairement de sens pour les identifiants). S'ils sont analysés, vous pouvez toujours le faire, mais seulement si vous savez exactement comment vos termes sont stockés ( l'analyseur standard les stocke en minuscules par exemple ).

34
xlecoustillier

Si vous utilisez un query_string query , vos AND et OR seront interprétés comme tels par la bibliothèque Lucene.

Cela vous permet de rechercher

(currentUserId OR currentCustomerId) AND currentComponent

par exemple. Par défaut, les valeurs seront recherchées dans tous les champs.

2
Alix Martin