Accéder au contenu principal Passer au contenu complémentaire

Clauses SELECT

Availability-noteDéprécié·e
Vous pouvez utiliser des clauses SELECT simples dans les appels de l'API REST.

Sélection de toutes les instances d'une entité

Vous pouvez interroger toutes les instances d'une entité. Par exemple, pour retourner toutes les instances des enregistrements de "Type1", utilisez la requête :

{
  "select": {
    "from": ["Type1"]
  }
}

L'élément "from" constitue un type de tableau, vous permettant de sélectionner plusieurs types. Cela ne signifie pas que la requête peut retourner toutes les instances de Type1 et de Type2. Le tableau est utilisé pour des jointures.

Pagination : début et limite

La pagination peut être nécessaire dans certains cas d'utilisation, tels que la construction d'une table. Elle peut être réalisée à l'aide des éléments "start" et "limit".

Par exemple, pour retourner les résultats commençant avec la première instance de "Type1" (index à 0), ainsi que les 10 instances suivantes, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "start": 0,
    "limit": 10
  }
}
Prenez en compte les points suivants :
  • L'exécution standard de telles requêtes implique la création d'une liste de limites de taille (limit) côté serveur. Si vous spécifiez une valeur élevée, des problèmes de performances ou une erreur de type OutOfMemoryError peuvent survenir. Par conséquent, assurez-vous d'utiliser la pagination avec des valeurs relativement basses pour l'élément limit.

  • Pour le code MDM, un élément limit ayant pour valeur Integer.MAX_VALUE (2^31 -1) n'indique aucune limite ("no limit"). Assurez-vous d'utiliser une stratégie de streaming plutôt qu'une liste de résultats. Cependant, cela signifie qu'une limite de (2^31 - 2) essayera de créer une liste de cette taille (causant généralement une erreur de type OutOfMemoryError).

Sélection des valeurs de champs

Plutôt que d'interroger l'enregistrement en entier, vous pouvez interroger un seul de ses champs.

Par exemple, pour retourner des valeurs du champ "id" de type "Type1", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/id"}
    ]
  }
}

Pour sélectionner plus d'un champ, répétez l'élément "field". Par exemple, pour retourner des valeurs des champs "id", "value1" et "value2" pour chaque enregistrement de "Type1", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/id"},
      {"field": "Type1/value1"},
      {"field": "Type1/value2"}
    ]
  }
}

Renommage (aliasing)

Pour des raisons client ou de nommage, vous souhaitez nommer différemment l'élément retourné. Ce type de renommage (aliasing) peut aider à différencier des valeurs en cas de problèmes de noms. Cette action peut être réalisée à l'aide de l'élément "alias".

Par exemple, pour retourner toutes les valeurs du champ "id" de toutes les instances de Type1, mais à la place de mettre des valeurs à l'intérieur d'un élément "id", l'élément entourant est nommé "a", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/id"},
      {
        "alias": [
          {"name": "a"},
          {"field": "Type1/id"}
        ]
      }
    ]
  }
}

Par exemple, utilisez la requête suivante pour retourner les résultats de "Type1/containedField1/value1" mis dans "v1" et "Type1/containedField2/value1" mis dans "v2", en évitant ainsi l'éventuel problème de noms. Ce problème aurait été retourné si "Type1/containedField1/value1" et "Type1/containedField2/value1" avaient été mis tous les deux dans un élément "value1" :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {
        "alias": [
          {"name": "v1"},
          {"field": "Type1/containedField1/value1"}
        ]
      },
      {
        "alias": [
          {"name": "v2"},
          {"field": "Type1/containedField2/value1"}
        ]
      }
    ]
  }
}

Valeurs de champs distinctes

Vous pouvez utiliser le mot-clé "distinct" pour obtenir toutes les valeurs distinctes pour le champ d'une entité.

Par exemple :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"distinct": {"field": "Type1/value1"}}
    ]
  }
}

Cette requête retourne toutes les valeurs distinctes pour le champ "value1" dans le type "Type1".

Vous pouvez également nommer différemment un résultat à l'aide de l'élément "alias". Par exemple :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {
        "alias": [
          {"name": "a0"},
          {"distinct": {"field": "Type1/value1"}}
        ]
      }
    ]
  }
}

Cette requête retourne toutes les valeurs distinctes pour le champ "value1", mais à l'intérieur d'un élément nommé "a0".

Compte

Vous pouvez compter le nombre de résultats retournés par une requête.

Par exemple, pour compter le nombre d'instances de Type1 disponibles, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"count": {}}
    ]
  }
}

Vous pouvez également associer l'opération de compte à des conditions afin de compter le nombre d'instances correspondant aux critères spécifiés.

Par exemple, pour retourner le nombre d'instances de Type1 ayant une valeur supérieure à 1 pour le champ "value1", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"count": {}}
    ],
    "where": {
      "gt": [
        {"field": "Type1/value1"},
        {"value": "1"}
      ]
    }
  }
}

Le compte peut également être utilisé dans des clauses ORDER_BY.

Maximum et minimum

Vous pouvez sélectionner la valeur maximale et/ou minimale d'un champ dans une entité.

Par exemple, pour récupérer la valeur la plus faible du champ "id" dans l'entité Type1, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"min": {"field": "Type1/id"}}
    ]
  }
}

Par exemple, pour récupérer la valeur la plus élevée du champ "id" dans l'entité Type1, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"max": {"field": "Type1/id"}}
    ]
  }
}

Par exemple, pour récupérer la valeur la plus élevée et la plus faible du champ "id" dans Type1, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"max": {"field": "Type1/id"}},
      {"min": {"field": "Type1/id"}}
    ]
  }
}

Tri par valeur de champ

Vous pouvez utiliser autant de clauses "order_by" que nécessaire dans une requête pour configurer l'ordre de tri dans le résultat retourné, soit par ordre décroissant ou croissant.

Par exemple, pour sélectionner toutes les instances de Type1 et trier les résultats par ID (du plus élevé au plus faible) et par valeur de champ "value1" (du plus faible au plus élevé), utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "order_bys": [
      {
        "order_by": [
          {"field": "Type1/id"},
          {"direction": "DESC"}
        ]
      },
      {
        "order_by": [
          {"field": "Type1/value1"},
          {"direction": "ASC"}
        ]
      }
    ]
  }
}

Tri par occurrence de valeur de champ

Vous pouvez également trier par occurrence de valeur de champ pour retourner la valeur la plus fréquente en premier jusqu'à la valeur la moins fréquente (en cas de tri par ordre décroissant "DESC").

Par exemple, cette requête permet de retourner de la valeur la plus fréquente à la valeur la moins fréquente pour le champ "value1" :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/value1"},
    ],
    "order_bys": [
      {
        "order_by": [
          {"count": {"field": "Type1/value1"}},
          {"direction": "DESC"}
        ]
      }
    ]
  }
}

Vous pouvez également inclure un champ "limit" dans la requête pour obtenir les N valeurs les plus fréquentes.

Par exemple, cette requête permet d'obtenir les 10 valeurs les plus fréquentes :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/value1"},
    ],
    "order_bys": [
      {
        "order_by": [
          {"count": {"field": "Type1/value1"}},
          {"direction": "DESC"}
        ]
      }
    ],
    "limit": 10
  }
}
Note InformationsRemarque : Ce type de requête ne fonctionne pas si vous utilisez la base de données DB2 ou MS SQL Server, car elles ne supportent pas la clause order by avec la fonction count.

Conditions

Les opérandes suivants peuvent être utilisés :

Opérande du langage de requêtes

Signification

eq

equals

gt / gte

supérieur à/supérieur ou égal à

lt / lte

inférieur à/ inférieur ou égal à

startsWith

commence par

contains

contient

isEmpty

est vide (")

isNull

est null

in spécifie plusieurs valeurs dans une clause WHERE
full_text effectue une recherche plein texte

Prenez en compte les points suivants :

  • La structure est toujours la suivante : "operand": { field, value }.
  • Les opérandes contains et full_text ne peuvent être utilisées avec d'autres opérateurs de recherche. Puisqu'une recherche plein texte couvre en interne toutes les conditions de contains et full_text, ces opérandes ne peuvent être combinées.
  • si le champ est de type numérique (int, short, integer, long, float, double, decimal) et que vous fournissez une valeur numérique pour celui-ci, la valeur peut être interprétée en étant ou non entourée de guillemets doubles. Sinon, la valeur doit être entourée de guillemets doubles. Assurez-vous de faire correspondre la valeur et le type d'élément. Par exemple, "value": "abc" est incorrect si le champ "Type1/id" est de type numérique.
  • Si vous n'avez accès à aucun des champs utilisés dans la condition, la requête ne retournera rien.
  • Lorsque vous cherchez un champ de type booléen égal à la valeur true, les enregistrements de données contenant uniquement la valeur true sont retournés.
  • Lorsque vous cherchez un champ de type booléen égal à la valeur false, à une valeur vide, ou à toute autre valeur, les enregistrements de données contenant les valeurs false et null sont retournés.
  • Lorsque vous cherchez un champ de type booléen qui n'est pas égal à la valeur true, les enregistrements de données contenant la valeur false et les valeurs null sont retournés.
  • Lorsque vous cherchez un champ de type booléen qui n'est pas égal à la valeur false, à une valeur vide, ou à toute autre valeur, les enregistrements de données contenant uniquement la valeur true sont retournés.

Exemple 1 : la requête ci-après, qui utilise l'argument eq, retourne toutes les instances de Types1 où l'élément id est égal à 1.

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"field": "Type1/id"},
        {"value": "1"}
      ]
    }
  }
}

Exemple 2 : la requête ci-après, qui utilise l'argument isEmpty, retourne toutes les instances de Store où la valeur de l'élément Address est égale à ".

{
  "select": {
    "from": ["Store"],
    "where": {
      "isEmpty": {
        "field": "Store/Address"
      }
    }
  }
}

Exemple 3 : la requête ci-après, qui utilise l'opérateur not et l'argument isNull, retourne toutes les instances de Store où la valeur de l'élément Address n'est pas null.

{
    "select": {
        "from": ["Store"],
        "where": {
            "not": {
                "isNull": {
                    "field": "Store/Address"
                }
            }
        }
    }
}

Condition sur les index

Vous pouvez spécifier un index pour votre condition, si le champ est un élément répétable. L'index vaut 0.

Par exemple, pour retourner toutes les instances de Type1 dont la seconde valeur du champ "list" est égale à "1", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"index": [
          {"field": "Type1/list"},
          1
        ]},
        {"value": "1"}
      ]
    }
  }
}

Conditions entre champs

Vous pouvez utiliser des conditions entre différents champs. Généralement, seul "eq" (EQUALS) est supporté pour de telles comparaisons.

Par exemple, pour retourner les instances de Type1 dont la valeur "id" est égale à "value1", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"field": "Type1/id"},
        {"value": {"field": "Type1/value1"}}
      ]
    }
  }
}

Opérateur in

Vous pouvez utiliser l'opérateur in au sein d'une requête.

Par exemple, pour retourner toutes les instances de Type1 où "id" vaut 1, 2 ou 5, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "in": [
        {"field": "Type1/id"},
        {"value": ["1","2","5"]}
      ]
    }
  }
}

Prenez en compte les points suivants :

  • si le champ est de type numérique (int, short, integer, long, float, double, decimal) et que vous fournissez une valeur numérique pour celui-ci, la valeur peut être interprétée en étant ou non entourée de guillemets doubles. Sinon, la valeur doit être entourée de guillemets doubles. Assurez-vous de faire correspondre la valeur et le type d'élément. Par exemple, "value": ["a", "b", "c"] est incorrect si le champ "Type1/id" est de type numérique.
  • La valeur "value" est formatée comme un tableau (array) JSON et les valeurs listées doivent être statiques. Par exemple, ["value1", "value2", "value3"...].
  • Seuls des champs de type simple au niveau racine sont supportés. Cependant, les champs obligatoires de clés étrangères multi-occurrence ne sont pas supportés.
  • L'opérateur in ne peut être utilisé avec la recherche plein texte.
  • L'opérateur in peut fonctionner avec l'opérateur not. Pour plus d'informations, consultez la section Opérateur not.

Opérateurs logiques

Pour permettre des requêtes plus complexes, des opérateurs booléens (and/or/not) peuvent être inclus. La structure est similaire à ce qui a été présenté précédemment "operator": { left, right }left et/ou right peuvent également être des opérateurs logiques.

Par exemple, pour retourner toutes les instances de Type1 où "id = 1 OR value1 = 0", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "or": [
        {
          "eq": [
            {"field": "Type1/id"},
            {"value": "1"}
          ]
        },
        {
          "eq": [
            {"field": "Type1/value1"},
            {"value": "0"}
          ]
        }
      ]
    }
  }
}

Un opérateur logique binaire (and/or) doit forcément avoir deux enfants. Par exemple, vous pouvez écrire une condition avec "a OR b OR c" :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "or": [
        {
          "eq": [
            {"field": "Type1/id"},
            {"value": "1"}
          ]
        },
        {
          "or": [
            {
              "eq": [
                {"field": "Type1/id"},
                {"value": "2"}
              ]
            },
            {
              "eq": [
                {"field": "Type1/value1"},
                {"value": "4"}
              ]
            }
          ]
        }
      ]
    }
  }
}

Vous pouvez également mélanger les opérateurs logiques. Il n'existe aucune ambiguïté dans l'ordre d'évaluation des conditions.

Par exemple, pour retourner toutes les instances de Type1 où "(id = 1 OR (id = 2 and value1 = 4))", utilisez la requête qui mélange and et or :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "or": [
        {
          "eq": [
            {"field": "Type1/id"},
            {"value": "1"}
          ]
        },
        {
          "and": [
            {
              "eq": [
                {"field": "Type1/id"},
                {"value": "2"}
              ]
            },
            {
              "eq": [
                {"field": "Type1/value1"},
                {"value": "4"}
              ]
            }
          ]
        }
      ]
    }
  }
}  

Opérateur not

L'opérateur not est supporté et suit la structure suivante : "not": { condition }.

Par exemple, pour retourner toutes les instances de Type1 où la valeur "id" n'est pas égale à 1, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "not": {
        "eq": [
          {"field": "Type1/id"},
          {"value": "1"}
        ]
      }
    }
  }
}

Vous pouvez également utiliser l'opérateur not dans une condition plus complexe. Par exemple :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "not": {
        "or": [
          {
            "eq": [
              {"field": "Type1/id"},
              {"value": "2"}
            ]
          },
          {
            "eq": [
              {"field": "Type1/id"},
              {"value": "4"}
            ]
          }
        ]
      }
    }
  }
}

Vous pouvez utiliser l'opérateur not avec l'opérateur in. Le résultat de la requête n'inclut pas les instances où le champ spécifié a une valeur nulle.

Par exemple :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "not": {
        "in": [
            {"field": "Type1/id"},
            {"value": ["1","3","4","5"]}        
            ]
      }
    }
  }
}

Cela retourne toutes les instances de Type1 où "id" ne vaut aucune des valeurs listées, à savoir 1, 3, 4 et 5.

Plein texte (dans le cadre du champ)

Le langage de requêtes inclut un support pour la recherche en plein texte.

Par exemple, pour réaliser une recherche en plein texte sur le champ "Type1/id" avec la valeur "1", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "full_text": [
        {"field": "Type1/id"},
        {"value": "1"}
      ]
    }
  }
}

La requête en plein texte fonctionne également sur les sous-éléments. Par exemple, si vous avez la structure type suivante :

Type1
  * id
  * element
    * value1
    * value2

Puis la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "full_text": [
        {"field": "Type1/element"},
        {"value": "1"}
      ]
    }
  }
}

Équivaut à :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "or": [
        {
          "full_text": [
            {"field": "Type1/element/value1"},
            {"value": "1"}
          ]
        },
        {
          "full_text": [
            {"field": "Type1/element/value2"},
            {"value": "1"}
          ]
        }
      ]
    }
  }
}

Plein texte (dans le cadre de l'entité)

Si vous ne souhaitez spécifier aucun champ, mais que vous recherchez une valeur dans l'entité, la requête suivante vous montre comment le faire :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "full_text": [
        {"value": "1"}
      ]
    }
  }
}

Si vous omettez de préciser le champ, MDM effectue la recherche en plein texte sur tous les champs de Type1.

Champs de métadonnées

MDM ajoute des champs "metadata" pour les enregistrements qu'il gère. Ces champs ne sont pas présents dans le modèle de données utilisateur·rice, mais peuvent être utilisés dans la requête.

Les champs de métadonnées supportés sont :

  • taskId (aussi connu comme groupId)
  • timestamp (dernière date de modification)
  • groupSize

Pour le stockage de préparation (staging), des champs de métadonnées supplémentaires existent :

  • Erreur (Staging error)
  • Source (Staging source)
  • Statut (Staging status)
  • Clé de bloc (Staging block key)
  • Tâches (Staging has task)

    Notez que le champ "Staging has task" indique si une tâche Talend Data Stewardship est liée à l'enregistrement.

Si la requête contient des champs "staging_" uniquement, vous pouvez rencontrer une erreur qui indique les expressions incompatibles. Les expressions incompatibles sont vérifiées dans les champs, les conditions, les expressions de tri et de jointure sélectionnés.

Obtention de valeurs de champs de métadonnées

Pour obtenir un champ de métadonnées, utilisez l'élément "metadata" plutôt que "field" dans les champs sélectionnés, comme l'exemple suivant le montre :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"metadata": "timestamp"},
      {"metadata": "task_id"},
      {"metadata": "group_size"},
      {"metadata": "staging_error"},
      {"metadata": "staging_source"},
      {"metadata": "staging_status"},
      {"metadata": "staging_blockkey"},
      {"metadata": "staging_hastask"}
    ]
  }
}

Vous pouvez également mélanger les champs de l'entité et ceux de l'enregistrement :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"metadata": "timestamp"},
      {"metadata": "task_id"},
      {"field": "Type1/id"}
    ]
  }
}

Vous pouvez utiliser le mot-clé "distinct" pour les champs de métadonnées. Par exemple, pour retourner toutes les valeurs distinctes de "taskId" mises dans un élément nommé "distinctTaskId", utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {
        "alias": [
          {"name": "distinctTaskId"},
          {"distinct": {"metadata": "task_id"}}
        ]
      }
    ]
  }
}

Conditions incluant des champs de métadonnées

Vous pouvez inclure des champs de métadonnées dans des conditions. Quant aux champs sélectionnés, utilisez simplement l'élément "metadata" plutôt que "field". Par exemple :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"metadata": "task_id"},
        {"value": "1"}
      ]
    }
  }
}

Mise en cache

MDM peut mettre en cache les résultats de la requête. Dans ce cas, il garde la requête en cache et remet le résultat mis en cache chaque fois que cette requête est exécutée.

Par exemple, pour mettre en cache le résultat d'une requête, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"field": "Type1/id"},
        {"value": "1"}
      ]
    },
    "cache": true
  }
}

Par défaut, la valeur de l'élément "cache" est false, mais la requête est toujours valide :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"field": "Type1/id"},
        {"value": "1"}
      ]
    },
    "cache": false
  }
}

Un résultat mis en cache peut contenir au maximum 50 enregistrements. When the query yields too many results, the following log will appear in the MDM log at DEBUG level: Query is yielding more results than cache is allowed to keep, bypassing cache for query.

Jointure entre différents types

Les jointures sont un moyen de récupérer des données d'un autre type suivant les clés étrangères.

Par exemple, vous pouvez récupérer l'élément "Address's street" en suivant la clé étrangère entre les types Person et Address.

Voici un exemple de jointure simple :

{
  "select": {
    "from": [
      "Type1",
      "Type2",
    ],
    "fields": [
      {"field": "Type1/id"},
      {"field": "Type2/value1"}
    ],
    "joins": [
      {
        "from": "Type1/fk2",
        "on": "Type2/id"
      }
    ]
  }
}

Cette requête retourne tous les éléments "id" de Type1 ainsi que les éléments "value1" situés dans Type2. La jointure s'effectue en utilisant l'élément "fk2" dans Type1.

Vous pouvez également effectuer plusieurs jointures dans la requête. Par exemple :

{
  "select": {
    "from": [
      "Type1",
      "Type2",
      "Type3"
    ],
    "fields": [
      {"field": "Type1/id"},
      {"field": "Type2/value1"},
      {"field": "Type3/value2"}
    ],
    "joins": [
      {
        "from": "Type1/fk2",
        "on": "Type2/id"
      },
      {
        "from": "Type2/fk3",
        "on": "Type3/id"
      }
    ]
  }
}

Cette requête affiche la valeur "id" de Type1, la valeur "value1" de Type2 et la valeur "value1" de Type3. La valeur "value1" de Type3 est obtenue via une jointure entre Type1, Type2 et Type3.

Vous pouvez également attacher des jointures pour la clé composite dans la requête. Par exemple :

{
    "select": {
        "from": [
            "Type2",
            "Type1"
        ],
        "fields": [{
                "alias": [{
                        "name": "Type2/idC"
                    },
                    {
                        "field": "Type2/idC"
                    }
                ]
            },
            {
                "alias": [{
                        "name": "Type2/idD"
                    },
                    {
                        "field": "Type2/idD"
                    }
                ]
            },
            {
                "alias": [{
                        "name": "Type2/name"
                    },
                    {
                        "field": "Type2/name"
                    }
                ]
            },
            {
                "alias": [{
                        "name": "Type1/name"
                    },
                    {
                        "field": "Type1/name"
                    }
                ]
            },
            {
                "alias": [{
                        "name": "Type2/fk"
                    },
                    {
                        "field": "Type1/[idA][idB]"
                    }
                ]
            }
        ],
        "joins": [{
            "from": "Type2/fk",
            "on": "Type1/[idA][idB]"
        }]
    }
}

Cette requête retourne "idC", "idD", "name" et la clé étrangère depuis Type2 et "name" depuis Type1. La jointure est effectuée à l'aide de la clé étangère composite "fk" dans Type2.

Note InformationsRemarque : Avoir plusieurs jointures sur la même entité dans une seule requête n'est pas supporté, sauf pour les clés composites.

Opérateurs liés à l'historique - opérateur “as of"

L'opérateur "as_of" vous permet de récupérer un enregistrement tel qu'il était à une date donnée.

Par exemple :

{
  "select": {
    "from": ["Type1"],
    "as_of": {
      "date": "1000"
    }
  }
}

L'opérateur "as of" n'échoue pas si aucun historique n'est disponible. À la place, il retourne l'enregistrement à son état actuel.

La navigation dans l'historique dépend du journal. Si vous insérez des données directement dans la base de données SQL ou si vous désactivez la création d'événements pour les composants tMDMOutput/tMDMDelete, vous n'aurez qu'un historique partiel.

MDM peut uniquement construire un historique des enregistrements basé sur les informations qu'il a stocké au niveau des mises à jour : si vous désactivez le journal pour des mises à jour, l'historique ne peut être complet et précis.

Par exemple, pour retourner toutes les instances de Type1 ayant comme valeur celle qu'elles avaient une seconde après le 1er janvier 1970 (1 000 ms après EPOCH), utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "as_of": {
      "date": "1970-01-01T00:00:01"
    }
  }
}

Raccourcis de navigation dans l'historique

Les éléments "date" pour les éléments "as_of" supportent des raccourcis utiles :

  • yesterday : il y a 24 heures.
  • creation : date de création de l'enregistrement. Lorsque vous utilisez l'élément "creation", vous ne pouvez pas utiliser le paramètre "swing". Autrement, vous devez vous attendre à ce qu'une erreur survienne.
  • now : date actuelle.

Par exemple, pour retourner toutes les instances de Type1 comme elles étaient hier (il y a 24 heures), utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "as_of": {
      "date": "yesterday"
    }
  }
}

Filtrage de l'historique (par ID)

Vous souhaitez filtrer les enregistrements de l'historique au lieu d'obtenir toutes les instances.

Par exemple, pour retourner l'instance de Type1 ayant comme valeur "id = 1", comme elle l'était au 1er janvier 1970, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "eq": [
        {"field": "Type1/id"},
        {"value": "1"}
      ]
    },
    "as_of": {
      "date": "1000"
    }
  }
}

Vous pouvez améliorer cette requête en utilisant toutes les conditions avec "as_of", vous permettant d'interroger les valeurs précédentes. Les conditions n'ont pas besoin d'être uniquement sur des éléments "id".

Par exemple, pour retourner l'instance de Type1 qui contenait "text" au 1er janvier 1970, utilisez la requête :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "contains": [
        {"field": "Type1/value"},
        {"value": "text"}
      ]
    },
    "as_of": {
      "date": "1000"
    }
  }
}

Cependant, cette requête rencontre des problèmes d'extensibilité, puisqu'elle peut forcer MDM à construire un jeu complet d'instances de Type1. Cela mène alors à des problèmes de mémoire, si des états sont calculés en mémoire.

Utilisation de jointure avec as_of

Vous pouvez utiliser l'élément "joins" dans une requête avec l'opérateur "as_of".

Par exemple, utilisez la requête ci-dessous pour retourner trois champs ("id", "value1", "value2") venant de deux types ("Type1", "Type2") :

{
  "select": {
    "from": [
      "Type1",
      "Type2"
    ],
    "fields": [
      {"field": "Type1/id"},
      {"field": "Type1/value1"},
      {"field": "Type2/value2"}
    ],
    "joins": [
      {
        "from": "Type1/fk2",
        "on": "Type2/id"
      }
    ],
    "as_of": {
      "date": "1000"
    }
  }
}

Les valeurs retournées ont les caractéristiques ci-dessous :

  • L'élément "as_of" retourne les valeurs de "Type1" comme elles étaient au 01/01/1970.
  • La valeur de la clé étrangère utilisée pour Type2 est la valeur de la clé étrangère au 01/01/1970.
  • Les valeurs pour Type2 sont celles au 01/01/1970.

Sécurité et rôles utilisateur·rice

Rappelez-vous que la requête transmise au service n'est pas toujours celle que MDM exécute. Avant l'exécution de la requête, MDM réduit tous les éléments auxquels l'utilisateur ou l'utilisatrice connecté ne peut avoir accès, à savoir les champs, les conditions et les ordres de tri sélectionnés. Tous les éléments masqués aux utilisateurs et utilisatrices sont retirés de la requête sans reporter d'erreur.

Par exemple :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/id"},
	  {"field": "Type1/secret_field"}
    ]
  }
}

Dans cet exemple, MDM retire automatiquement l'élément "secret_field" de la requête si l'utilisateur ou l'utilisatrice actuel (étant l'utilisateur ou l'utilisatrice connecté à l'API REST) n'a pas accès à l'élément "secret_field". Cependant, la requête exécutée actuellement est la suivante :

{
  "select": {
    "from": ["Type1"],
    "fields": [
      {"field": "Type1/id"}
    ]
  }
}

Autre exemple de ce genre de requêtes :

{
  "select": {
    "from": ["Type1"],
    "where": {
      "gt": [
        {"field": "Type1/secret_field"},
        {"value": "1"}
      ]
    }
  }
}

Cette requête est lue de la manière suivante "retourne toutes les instances de Type1 où la valeur secret_field de Type1 est supérieure à 1". Le résultat retourné doit être les instances de Type1 où secret_field > 1.

Cependant, si les rôles de l'utilisateur ou de l'utilisatrice actuel ne lui donnent pas accès à l'élément "secret_field", la requête actuelle devient :

{
  "select": {
    "from": ["Type1"]
  }
}

Cette requête est lue de la manière suivante "retourne toutes les instances de Type1". Le résultat retourné doit être toutes les instances de Type1 car l'utilisateur ou l'utilisatrice actuel n'a pas accès à l'élément "secret_field".

Ceci empêche les utilisateurs et utilisatrices dépourvus de droits d'accès de deviner indirectement les valeurs de l'élément "secret_field", en utilisant des conditions de valeurs sur ce champ.

Cette page vous a-t-elle aidé ?

Si vous rencontrez des problèmes sur cette page ou dans son contenu – une faute de frappe, une étape manquante ou une erreur technique – dites-nous comment nous améliorer !