IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

NoSQL Discussion :

[Elasticsearch] must_not fonctionne si on le place avant une requête nested mais pas si on le place dedans


Sujet :

NoSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut [Elasticsearch] must_not fonctionne si on le place avant une requête nested mais pas si on le place dedans
    Bonjour,

    Ma question concerne la construction de requête pour elasticsearch, je ne sais pas s'il s'agit de la bonne partie du forum pour la poser.

    J'écris une application pour rechercher des logs dans l'elastic de mon organisation et l'utilisateur peut rechercher des requêtes nested sous cette forme :

    pathName:{ field1: "value1" AND field2: "value2" OR field3: "value3" }
    J'aimerais que l'utilisateur puisse demander que certains champs dans la requête nested ne soient pas matchés.

    Je peux le faire si je veux que toute la requête nested soit non matché, cela donne la requête suivante:

    NOT pathName:{ field1: "value1" }
    Et à partir de cette chaîne de caractère, je peux générer la requête suivante qui fonctionne bien :

    (La clause must_not[] est placée avant la clause nested parceque c'est l'ensemble de la clause nested que je ne veux pas matcher)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    "query": {
        "bool": {
        	"filter": [
                {
                    "bool": {
                        "must_not": [
                            {"nested": {
                                "path": 'pathName',
                                "query": {
                                    {"bool": {
                                        "should": [
                                            {
                                                "match": {
                                                    "pathName.field1": "value1"
                                                }
                                            }
                                        ],
                                        "minimum_should_match": 1
                                    }}
                                }
                            }}
                        ]
                    }
                }
        		{"range": 
                    {
        			    "@timestamp": {
        			    	"format": 'strict_date_optional_time',
        			    	"gte": "Sat Jul 09 2022 02:00:00 GMT+0200 (heure d’été d’Europe centrale)",
        			    	"lte": "Mon Aug 08 2022 02:00:00 GMT+0200 (heure d’été d’Europe centrale)"
                        }
                    }
                }
            ]
        }
    }
    La requête ci-dessus fonctionne bien et renvoie le résultat attendu.

    J'aimerais maintenant que mon utilisateur puisse demander à l'intérieur d'une requête nested de matcher certains champs et de ne pas matcher d'autres champs comme ceci:
    pathName:{ NOT field1: "value1" AND field2: "value2" OR NOT field3: "value3" }
    Par exemple, pour la requête suivante :

    pathName:{ NOT field1: "value1" }
    (En pratique, il y aura évidemment plus d'un élément dans la requête nested , mais pour simplifier, je n'ai mis qu'un seul élément dans la requête nested )

    Je veux obtenir tous les objets qui ne match pas pathName.field1:value1.

    A partir de la chaîne de caractère précédente, j'arrive à générer la requête suivante :

    (La clause must_not[] est alors placée à l'intérieur de la clause nested car ce n'est qu'une partie des éléments de la clause nested que nous ne voulons pas matcher)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
     
    "query": {
        "bool": {
        	"filter": [
                {"nested": {
                    "path": 'pathName',
                    "query": {
                        {"bool": {
                            "must_not": [
                                {
                                    "bool": {
                                        "should": [
                                            {
                                                "match": {
                                                    "pathName.field1": "value1"
                                                }
                                            }
                                        ],
                                        "minimum_should_match": 1
                                    }
                                }
                            ]
                        }}
                    }
                }},
        		{"range": 
                    {
        			    "@timestamp": {
        			    	"format": 'strict_date_optional_time',
        			    	"gte": "Sat Jul 09 2022 02:00:00 GMT+0200 (heure d’été d’Europe centrale)",
        			    	"lte": "Mon Aug 08 2022 02:00:00 GMT+0200 (heure d’été d’Europe centrale)"
                        }
                    }
                }
            ]
        }
    }
    Mais cette requête renvoie les résultats sans prendre en compte les clauses must_not[] contenues dans la requête nested.

    N'est-il pas possible de spécifier une clause must_not[] à l'intérieur d'une requête nested ou est-ce que je génère mal la requête envoyée à elastic ?

    Merci d'avance si vous prenez le temps de m'aider.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 622
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 622
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    En marge de votre question je note une combinaison d'opérateurs ET et OU sans parenthèses, c'est peu lisible et risqué, les résultats obtenus ne seront peut être pas ceux attendus :

    field1: "value1" AND field2: "value2" OR field3: "value3".

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut
    Bonjour,

    J'aurai en effet du le préciser, l'opérateur OR à la priorité sur l'opérateur AND mais il y a la possibilité de mettre une expression entre parenthèses pour spécifier un niveau de détail supplémentaire.

    Par exemple, la chaîne de caractère :
    champs_1: "valeur1" AND (champs_2: "valeur2" OR champs_3: "valeur3")
    signifie je veux les objets qui ont le champs 1 avec la valeur 1 et qui ont aussi soit le champs 2 avec la valeur 2, soit le champs 3 avec la valeur 3.

    Par contre la chaîne de caractère :
    champs_1: "valeur1" AND champs_2: "valeur2" OR champs_3: "valeur3"
    signifie je veux les objets qui ont à la fois le champs 1 avec la valeur 1 et le champs 2 avec la valeur 2 ou alors les objets qui ont le champs 3 avec la valeur 3.

Discussions similaires

  1. Réponses: 2
    Dernier message: 11/02/2015, 18h14
  2. [AC-2010] Une requete qui ne fonctionne que si on enregistre avant ? ! ?
    Par mikadeejay dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 21/01/2014, 16h42
  3. Réponses: 9
    Dernier message: 09/05/2013, 17h27
  4. condition if avant une requête sql
    Par Amelie MOREAU dans le forum Langage
    Réponses: 4
    Dernier message: 24/04/2013, 13h52
  5. Ne prendre que les infos avant une certaine date??
    Par mythtvtalk.com dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 08/07/2003, 10h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo