Référence : tri et filtrage

Ce document complète la documentation de référence sur projects.alertPolicies, projects.notificationChannels et projects.uptimeCheckConfigs dans l'API Cloud Monitoring. Elle fournit des détails syntaxiques sur les paramètres filter et orderBy lorsqu'ils sont utilisés par l'API.

Les méthodes d'API suivantes sont compatibles avec les paramètres filter et orderBy:

La méthode API suivante n'accepte que le paramètre filter:

Principes de base du tri et du filtrage

La possibilité de trier et de filtrer les résultats d'une opération list est indiquée par la présence des champs de chaîne filter et orderBy dans le corps de la requête de liste (consultez la documentation de référence de l'API pour voir si le corps de la requête inclut ces champs). Ces deux champs font appel à une syntaxe simple pour faire référence aux champs de l'objet trié ou filtré.

Syntaxe de l'ordre de tri

Le champ orderBy est constitué d'une liste de chemins d'accès à des champs séparés par des virgules et éventuellement précédés d'un signe "moins" pour inverser l'ordre.

Par exemple, user_label.team,display_name effectue un tri par nom d'équipe dans l'ordre croissant, puis, pour les entrées de la même équipe, effectue un tri par nom d'affichage, également dans l'ordre croissant. Si vous ajoutez un signe moins devant l'un des champs séparés par une virgule, ce champ est trié par ordre décroissant. Par exemple, si vous essayez de réduire le niveau de détail de vos titres, vous pouvez utiliser -display_name.size pour effectuer un tri par longueur de titre, avec des objets classés du titre le plus long au titre le plus court.

Pour fournir un exemple plus réaliste, user_label.team,display_name regroupe d'abord les résultats par équipe (dans l'ordre lexicographique), puis, dans chaque groupe d'équipe, organise les résultats par titre (également dans l'ordre lexicographique).

Formellement, la syntaxe peut être décrite comme suit :

   ORDER_BY_SPEC :=
      # Comma-separated list of fields.
      ORDERED_FIELD_LIST

   ORDERED_FIELD_LIST :=
      # Single field on which to sort.
      ORDERED_FIELD

      # Sort by the first field and then by the remaining fields.
      | ORDERED_FIELD "," ORDERED_FIELD_LIST

   ORDERED_FIELD :=
      # Sort by the field in ascending order.
      FIELD_REFERENCE

      # Sort by the field in descending order.
      | "-" FIELD_REFERENCE

   FIELD_REFERENCE :=
      # Simple field reference
      FIELD_NAME

      # Map value or list index lookup. For string-valued keys, the
      # supplied key in this notation must be quoted.
      | FIELD_NAME "[" LITERAL "]"

   FIELD_NAME :=
      # Immediate element
      IDENTIFIER

      # Subfield dereference or map element dereference. Note that,
      # in the case of maps, the IDENTIFIER on the left can also
      # be the singular form of the name of the map. That is, it is
      # permitted to use `user_label.mykey` and not just
      # `user_labels.mykey`. This is done for consistency with the
      # metric filters which permit `resource.label.` and `metric.label.`
      # which are in the singular form even though the map is `labels`.
      | IDENTIFIER "." FIELD_NAME

   LITERAL :=
       # Number
       [0-9]+(.[0.9]+)?

       # String literal using single quotes. Note that strings must
       # always be quoted. This is to avoid ambiguity with attempting
       # to refer to the value of a field.
       |  '[^']*'

       # String literal using double quotes. Note that strings must
       # always be quoted. This is to avoid ambiguity with attempting
       # to refer to the value of a field.
       |  "[^"]*"

       # Literal boolean true.
       |  true

       # Literal boolean false.
       |  false

   IDENTIFIER :=
       # Non-digit followed by any number of letters or digits.
       [a-zA-Z_]+[a-zA-Z0-9_]*

Syntaxe des filtres

La syntaxe des filtres consiste en un langage d'expression simple permettant de construire un prédicat à partir d'un ou de plusieurs champs des objets filtrés. La négation, la conjonction et la disjonction sont écrites à l'aide des mots clés NOT, AND et OR. Les champs peuvent être comparés à des valeurs littérales à l'aide des opérateurs : (contient), = (égal à), > (supérieur à), < (inférieur à), >= (supérieur ou égal à), <= (inférieur ou égal à) et != (différent de). Les fonctions intégrées starts_with, ends_with, monitoring.regex.full_match (syntaxe RE2), ainsi que les propriétés intégrées empty et size permettent d'effectuer des comparaisons plus poussées.

Exemples

Pour renvoyer toutes les entrées avec un nom à afficher ou une description non vide dans lequel la clé active du champ user_labels est définie (avec n'importe quelle valeur) :

(NOT display_name.empty OR NOT description.empty) AND user_labels='active'

Pour renvoyer toutes les entrées dont la description contient "cloud" :

description:'cloud'

Pour renvoyer toutes les entrées dont le titre correspond à "Temp XXXX" :

display_name=monitoring.regex.full_match('Temp \\d{4}')

Spécification formelle

La syntaxe de l'expression de filtre peut être résumée comme suit :

   FILTER_EXPRESSION :=
         # Negation
         "NOT" FILTER_EXPRESSION

         # Short-circuiting AND
         | FILTER_EXPRESSION "AND" FILTER_EXPRESSION

         # Short-circuiting OR
         | FILTER_EXPRESSION "OR" FILTER_EXPRESSION

         # Implicit short-circuiting AND
         | FILTER_EXPRESSION FILTER_EXPRESSION

         # Parenthesized sub-expression
         | "(" FILTER_EXPRESSION ")"

         # Basic expression
         | SIMPLE_EXPRESSION

   SIMPLE_EXPRESSION :=
         # Field implicitly converted to boolean
         FIELD_REFERENCE

         # Field binary comparison. Note that the right-hand side must
         # be compatible with the type on the left-hand side; one cannot
         # compare a number with a string. Sensible implicit conversions
         # are permitted, however; comparing an integer and double will
         # succeed with appropriate conversion/widening taking place.
         | FIELD_REFERENCE OP LITERAL

         # Function invocation
         | FIELD_REFERENCE "=" FUNCTION_EXPRESSION

   FIELD_REFERENCE :=
         # Simple field reference
         FIELD_NAME

         # Map value or list index lookup. For string-valued keys, the
         # supplied key in this notation must be quoted.
         | FIELD_NAME "[" LITERAL "]"

   FIELD_NAME :=
         # Immediate element
         IDENTIFIER

         # Subfield dereference or map element dereference. Note that,
         # in the case of maps, the IDENTIFIER on the left can also
         # be the singular form of the name of the map. That is, it is
         # permitted to use `user_label.mykey` and not just
         # `user_labels.mykey`. This is done for consistency with the
         # metric filters which permit `resource.label.` and `metric.label.`
         # which are in the singular form even though the map is `labels`.
         | IDENTIFIER "." FIELD_NAME

   OP :=
         # Equality comparison. Should be avoided for double-valued fields.
         "="

         # Less than.
         | "<"

         # Greater than.
         | ">"

         # Less than or equal.
         | "<="

         # Greater than or equal.
         | ">="

         # Containment. This is equivalent to '=' for numeric types.
         | ":"

         # Not equal.
         | "!="

   LITERAL :=
       # Number
       [0-9]+(.[0.9]+)?

       # String literal using single quotes. Note that strings must
       # always be quoted. This is to avoid ambiguity with attempting
       # to refer to the value of a field.
       |  '[^']*'

       # String literal using double quotes. Note that strings must
       # always be quoted. This is to avoid ambiguity with attempting
       # to refer to the value of a field.
       |  "[^"]*"

       # Literal boolean true.
       |  true

       # Literal boolean false.
       |  false

   FUNCTION_EXPRESSION :=
       # Starts with.
       "starts_with" "(" LITERAL ")"

       # Ends with.
       |  "ends_with" "(" LITERAL ")"

       # Has substring. Takes an optional second argument that indicates whether
       # the substring matching is case-sensitive (true) or not (false).
       # The default is false, providing case-insensitive matches.
       |  "has_substring" "(" LITERAL [, [true|false]] ")"

       # Regular expression match.
       |  "monitoring.regex.full_match" "(" LITERAL ")"

   IDENTIFIER :=
       # Non-digit followed by any number of letters or digits.
       [a-zA-Z_]+[a-zA-Z0-9_]*

Champs pris en charge

Les champs pouvant être référencés dans les champs filter ou orderBy dépendent du type d'objet répertorié.

AlertPolicy

Les champs suivants peuvent être référencés dans filter et orderBy lors de l'énumération des objets AlertPolicy:

  • name
  • display_name
  • documentation.content
  • documentation.mime_type
  • user_labels
  • conditions.size
  • combiner
  • enabled
  • notification_channels

NotificationChannel

Les champs suivants peuvent être référencés dans filter et orderBy lors de l'énumération des objets NotificationChannel:

  • name
  • type
  • display_name
  • description
  • labels
  • user_labels

UptimeCheckConfig

Les champs suivants peuvent être référencés dans filter lors de l'énumération des objets UptimeCheckConfig:

  • display_name
  • user_labels
  • selected_regions
  • http_check.path
  • http_check.headers
  • http_check.port
  • tcp_check.port
  • monitored_resource.type
  • monitored_resource.labels

Rubriques avancées

Casse des champs

Les noms de champs peuvent être exprimés au format lower_case_with_underscores et camelCase. Cela signifie que display_name et displayName sont tous deux acceptés.

Chaînes

Propriétés intégrées

Les champs à valeur de chaîne comportent automatiquement une propriété size générée qui calcule le nombre de caractères Unicode dans la chaîne. Cela permet, par exemple, d'appliquer un filtre tel que display_name.size > 3 AND display_name.size < 10. En plus de size, les chaînes disposent également d'une propriété empty booléenne.

Ordre de tri

Lorsque vous répertoriez une chaîne dans orderBy, les chaînes sont comparées à l'aide d'un ordre lexicographique par octets dans la représentation UTF-8 de la chaîne. Les chaînes ne sont pas triées en fonction de l'ordre de classement Unicode.

Conversion implicite en booléen

Il est possible de convertir implicitement une chaîne en booléen dans un filtre, comme dans user_label.enabled. Notez que cette conversion n'est pas identique au test visant à vérifier que la chaîne n'est pas vide. Lors de cette conversion, le contenu de la chaîne est analysé en booléen, et les chaînes qui sont analysées sans ambiguïté en booléen prennent cette valeur booléenne. Si la chaîne n'est pas manifestement une valeur booléenne, les chaînes non vides sont interprétées comme étant "true" et les chaînes vides comme étant "false".

Les chaînes qui ne correspondent pas aux valeurs non sensibles à la casse "false", "f", "no", "n" ou "0" sont considérées comme certainement fausses. Les chaînes qui ne correspondent pas aux valeurs non sensibles à la casse "true", "t", "yes", "y" ou "1" sont considérées comme certainements vraies.

Listes

Propriétés intégrées

Les champs de type liste comportent automatiquement une propriété size générée qui calcule le nombre d'éléments figurant dans cette liste. Par exemple, vous pouvez utiliser notification_channels.size dans orderBy pour trier les règles d'alerte en fonction du nombre de canaux qu'ils envoient.

Utilisation dans des comparaisons binaires

Lors de la comparaison d'un champ de type liste à un littéral avec l'un des différents opérateurs binaires, la comparaison est interprétée comme appliquant une comparaison par élément, puis calculant l'opération OR des résultats. Par exemple, le filtre notification_channels:"123" renvoie la valeur "true" si l'un des canaux de notification a "123" comme sous-chaîne. Pour l'opérateur !=, plus précisément, la comparaison par élément est combinée à l'opérateur AND plutôt qu'à l'opérateur OR. Autrement dit, pour !=, aucun des éléments n'est autorisé à correspondre. Ou, pour reformuler, x!=y équivaut logiquement au pseudo-code x[0]!=y AND x[1]!=y AND ... AND x[x.size-1]!=y, tandis que x=y équivaut logiquement au pseudo-code x[0]=y OR x[1]=y OR ... OR x[x.size-1]=y. Cette incohérence est conçue pour répondre à l'intention probable de x!=y et éviter toute confusion avec une expression renvoyant des résultats contenant la valeur interdite/filtrée.

En plus de restreindre la liste dans son ensemble, vous pouvez également faire référence à des entrées de liste spécifiques via l'opérateur d'indexation ([]). Par exemple, vous pouvez utiliser notification_channels[0]:"123" pour tester uniquement le premier élément. Une valeur par défaut (vide, zéro, etc.) est générée dans le cas d'index hors limites.

Conversion implicite en booléen

Lorsqu'une liste est spécifiée dans un filtre sans comparaison binaire, elle est convertie implicitement en booléen. Cette conversion est différente du test visant à vérifier que la liste n'est pas vide. a_list et NOT a_list.empty renvoient des résultats différents pour {false, false, false} ou toute autre liste non vide dont les valeurs sont toutes la valeur booléenne false ou sont implicitement converties en valeur booléenne.

Maps

Propriétés intégrées

Les champs de type carte comportent automatiquement une propriété size générée qui calcule le nombre d'éléments figurant dans cette carte. Par exemple, vous pouvez utiliser user_labels.size dans orderBy pour effectuer un tri par nombre de libellés utilisateur définis. De même, une propriété empty de valeur booléenne est également générée automatiquement.

Test de l'existence d'une clé

Les cartes peuvent être comparées aux valeurs littérales avec les différents opérateurs binaires compatibles. L'interprétation équivaut logiquement à la projection de la carte dans une liste en extrayant les clés de la carte, puis en exécutant la comparaison. Pour donner un exemple, vous pouvez utiliser user_labels="phase" pour déterminer si la carte user_labels contient une clé dont la valeur est égale à "phase".

Référencer des valeurs par clé

Les entrées de carte peuvent être référencées à l'aide de l'une des deux notations suivantes : notation par points (.) et notation par index ([]). Par exemple, vous pouvez utiliser user_labels.team ou user_labels['team'] pour faire référence à la valeur correspondant à la clé "team" du champ user_labels. Par souci de cohérence avec l'API de métriques qui utilise les préfixes metric.label. et resource.label. plutôt que metric.labels. et resource.labels., les champs de mappage peuvent également être référencés à l'aide du singulier du nom (par exemple, user_label.team est également autorisé). Notez que, pour les clés nommées size ou empty, vous devez utiliser la notation par index. La notation par points fera référence aux propriétés de carte intégrées.

Conversion implicite en booléen

Dans les conversions implicites en valeurs booléennes, une map est considérée comme vraie si elle n'est pas vide et qu'au moins une map *value : est convertie implicitement en true. Cela ne revient pas à effectuer un test vérifiant qu'une carte n'est pas vide.

Trier par type de composé

Tous les champs pouvant être référencés dans un filtre peuvent également l'être dans order_by. Cela s'applique également aux types complexes et composés. L'ordre de tri de ces types est stable et bien défini, mais pas nécessairement intuitif. Cette utilisation est donc déconseillée, mais autorisée.

Listes

Les listes sont comparées à l'aide d'une comparaison lexicographique par élément, la plus petite liste apparaissant en premier si leurs éléments communs sont égaux. Pour donner un exemple, {0, 1} est inférieur à {0, 2}, mais supérieur à {0}.

Maps

Les cartes sont comparées en effectuant une comparaison par élément de leurs valeurs correspondant à l'union de leurs clés. Pour les clés définies dans une carte, mais pas dans l'autre, une valeur par défaut (vide, zéro, etc.) est utilisée pour la comparaison. Pour donner un exemple, {"x":0, "y":0} est inférieur à {"x":1, "y":1}, mais supérieur à {"a":-1} et égal à {}.