Article
· Jan 21 5m de lecture

Interrogation de données dynamiques à l'aide d'ASQ

IRIS 2023.3.0 ASQ

Abstract Set Query, ASQ, est un super ensemble de JSON Path Language (JPL), qui a été introduit pour la première fois par la norme ISO SQL 2016. JPL n'est défini que dans le contexte de SQL. Dans la version 2023.3, nous avons introduit des classes qui implémententent ASQ. Cela fonctionne sur n'importe quelle implémentation de %Library.AbstractSet. La syntaxe complète pour ASQ sera documentée plus tard. Ceci n’est qu’une brève introduction à quelques-unes de ses fonctionnalités. Cette implémentation est également livrée avec un utilitaire intéressant, comme vous le verrez !

Tout d’abord, récupérons quelques données de la base de données de la LNH. Cette étape nécessite une configuration SSL/TLS valide. J'ai nommé le mien Default.

USER>set data = ##class(%Net.Http).GetJson("https://api.nhle.com/stats/rest/en/team",{"SSLConfiguration":"Default"})

Cela peut prendre quelques secondes. Il s'agit d'un objet de réponse. Il a des champs de haut niveau de - eh bien, voyons. Je pourrais juste faire une jolie impression des données mais elles sont assez volumineuses. Je veux juste les noms des champs.

USER>set iterator = data.iterator() while iterator.hasNext() { write !,iterator.next().key }  
httpStatus
message
content

C'est le contenu qui nous intéresse, nous allons donc recommencer, cette fois en itérant sur la valeur du champ de contenu. Je suppose que je devrais ajouter une fonctionnalité pour imprimer une arborescence des données. Peut-être la semaine prochaine.

USER>set iterator = data.content.iterator() while iterator.hasNext() { write !,iterator.next().key }
data
total

Enfin nous allons jeter un coup d'oeil aux données.

Je veux souligner quelque chose ici. Le code que j'ai exécuté n'a pas changé autre que l'objet à partir duquel j'ai obtenu l'itérateur. Le reste du commandement est resté le même. En quelques lignes de code, j'ai pu implémenter l'affichage de l'arborescence. Il existe une fonction similaire dans 2023.3.0 qui pourrait être intéressante. Prenons donc une instance du tableau de données (je sais que c'est un tableau parce que j'ai jeté un coup d'œil. Désolé.)

USER>:pp data.content.data.get(0)
do ##class(%ASQ.SetUtils).pp(data.content.data.get(0))
{
  "id": 11,
  "franchiseId": 35,
  "fullName": "Atlanta Thrashers",
  "leagueId": 133,
  "rawTricode": "ATL",
  "triCode": "ATL"
}

J'utilise un pseudonyme ici. Vous pouvez voir l'appel qu'il effectue - %ASQ.SetUtils.pp. Passez simplement dans l'oref.

Les données que nous avons récupérées contiennent les équipes actuellement dans la NHL. Appliquons quelques expressions ASQ, juste pour jouer un peu. La première partie d'une expression ASQ est la valeur de base. Il est référencé par « $ ».

USER>:pp data.apply("$.content.data[0 to 3]") 
do ##class(%ASQ.SetUtils).pp(data.apply("$.content.data[0 to 3]"))
[
  {
    "id": 11,
    "franchiseId": 35,
    "fullName": "Atlanta Thrashers",
    "leagueId": 133,
    "rawTricode": "ATL",
    "triCode": "ATL"
  },
  {
    "id": 34,
    "franchiseId": 26,
    "fullName": "Hartford Whalers",
    "leagueId": 133,
    "rawTricode": "HFD",
    "triCode": "HFD"
  },
  {
    "id": 31,
    "franchiseId": 15,
    "fullName": "Minnesota North Stars",
    "leagueId": 133,
    "rawTricode": "MNS",
    "triCode": "MNS"
  },
  {
    "id": 32,
    "franchiseId": 27,
    "fullName": "Quebec Nordiques",
    "leagueId": 133,
    "rawTricode": "QUE",
    "triCode": "QUE"
  }
]

Cette expression vient de récupérer les membres du tableau de données de 0 à 3 – quatre d'entre eux.
L'expression [0 TO 3] est appelée expression d'accesseur de tableau. Elle autorise un caractère générique comme [*], un index comme [5] par exemple, un index relatif comme [last], une plage comme [1 TO 3], une liste de virgules d'index, de plage et relatif. [0, 2, 4, 5 À 7, dernier].
L'ordre des expressions d'index n'a pas d'importance mais elles seront renvoyées dans l'ordre que vous spécifiez :

USER>:pp data.content.data.apply("$[0 TO 1,last]")
do ##class(%ASQ.SetUtils).pp(data.content.data.apply("$[0 TO 1,last]"))
[
  {
    "id": 11,
    "franchiseId": 35,
    "fullName": "Atlanta Thrashers",
    "leagueId": 133,
    "rawTricode": "ATL",
    "triCode": "ATL"
  },
  {
    "id": 34,
    "franchiseId": 26,
    "fullName": "Hartford Whalers",
    "leagueId": 133,
    "rawTricode": "HFD",
    "triCode": "HFD"
  },
  {
    "id": 9,
    "franchiseId": 30,
    "fullName": "Ottawa Senators",
    "leagueId": 133,
    "rawTricode": "OTT",
    "triCode": "OTT"
  }
]
USER>:pp data.content.data.apply("$[last, 0 TO 1]")
do ##class(%ASQ.SetUtils).pp(data.content.data.apply("$[last, 0 TO 1]"))
[
  {
    "id": 9,
    "franchiseId": 30,
    "fullName": "Ottawa Senators",
    "leagueId": 133,
    "rawTricode": "OTT",
    "triCode": "OTT"
  },
  {
    "id": 11,
    "franchiseId": 35,
    "fullName": "Atlanta Thrashers",
    "leagueId": 133,
    "rawTricode": "ATL",
    "triCode": "ATL"
  },
  {
    "id": 34,
    "franchiseId": 26,
    "fullName": "Hartford Whalers",
    "leagueId": 133,
    "rawTricode": "HFD",
    "triCode": "HFD"
  }
]

Vient ensuite l’accesseur de membre. L'accesseur de membre est simplement un point suivi du nom du membre, également appelé nom de champ. Il existe également un caractère générique de membre, également indiqué par un astérisque. Les accesseurs membres sont nécessaires et utiles mais pas très excitants.

Ce qui est plus intéressant, c'est le comportement lorsqu'une valeur membre est un tableau. Nous pouvons filtrer n'importe quelle valeur, qu'il s'agisse d'un tableau ou d'un objet. Probablement même un sens littéral. Obtenons donc une liste de toutes les équipes de nos données dont le nom commence par la lettre « M ». Dans cette expression, le @ dans l'expression de filtre fait référence à la valeur actuelle.

USER>:pp data.content.data.apply("$[*]?(@.fullName STARTS WITH 'M').fullName")
do ##class(%ASQ.SetUtils).pp(data.content.data.apply("$[*]?(@.fullName STARTS WITH 'M').fullName"))
[
  "Minnesota North Stars",
  "Montreal Wanderers",
  "Montreal Maroons",
  "Montréal Canadiens",
  "Minnesota Wild"
]
Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer