web-dev-qa-db-fra.com

Existe-t-il un langage de requête pour JSON?

Existe-t-il un langage (à peu près) SQL ou similaire à XQuery pour interroger JSON?

Je pense à de très petits ensembles de données qui correspondent bien à JSON où il serait agréable de répondre facilement à des requêtes telles que "quelles sont toutes les valeurs de X où Y> 3" ou d'effectuer les opérations de type SUM/COUNT habituelles.

Comme exemple complètement inventé, quelque chose comme ceci:

[{"x": 2, "y": 0}}, {"x": 3, "y": 1}, {"x": 4, "y": 1}]

SUM(X) WHERE Y > 0     (would equate to 7)
LIST(X) WHERE Y > 0    (would equate to [3,4])

Je pense que cela fonctionnerait à la fois côté client et côté serveur, les résultats étant convertis dans la structure de données spécifique au langage appropriée (ou peut-être conservés au format JSON)

Une rapide recherche sur Google suggère que les gens y ont réfléchi et mis en œuvre quelques éléments ( JAQL ), mais cela ne semble pas être un usage standard ni un ensemble de bibliothèques. a encore émergé. Bien que chaque fonction soit relativement simple à mettre en œuvre seule, si quelqu'un l'a déjà bien fait, je ne veux pas réinventer la roue.

Aucune suggestion?

Edit: c’est peut-être une mauvaise idée ou JSON est un format trop générique pour ce que je pense. La raison pour laquelle nous souhaitons un langage de requête plutôt que de simplement faire la sommation/etc directement, est que j’espère construire les requêtes dynamiquement basées sur l'entrée de l'utilisateur. Un peu comme l'argument selon lequel "nous n'avons pas besoin de SQL, nous pouvons simplement écrire les fonctions dont nous avons besoin". Cela finit par devenir incontrôlable ou vous finissez par écrire votre propre version de SQL lorsque vous le poussez de plus en plus loin. (D'accord, je sais que c'est un argument un peu ridicule, mais vous avez l'idée ..)

205
allclaws

Bien sûr, que diriez-vous de:

Ils semblent tous être un peu en cours, mais travaillent dans une certaine mesure. Ils sont également similaires à XPath et XQuery sur le plan conceptuel; même si XML et JSON ont des modèles conceptuels différents (hiérarchique vs objet/structure).

[~ # ~] éditer [~ # ~] Sep-2015: En fait, il existe maintenant JSON Pointer le standard qui permet très parcours simple et efficace du contenu JSON. Non seulement il est formellement spécifié, mais il est également pris en charge par de nombreuses bibliothèques JSON. Je dirais donc qu’il s’agit d’un véritable critère utile, même si, en raison de son caractère expressif limité, il peut être considéré ou non comme un langage de requête.

82
StaxMan

Je recommanderais mon projet sur lequel je travaille s'appelle jLinq . Je cherche des commentaires donc je serais intéressé à entendre ce que vous pensez.

Si vous permet d'écrire des requêtes similaires à celles de LINQ ...

var results = jLinq.from(records.users)

    //you can join records
    .join(records.locations, "location", "locationId", "id")

    //write queries on the data
    .startsWith("firstname", "j")
    .or("k") //automatically remembers field and command names

    //even query joined items
    .equals("location.state", "TX")

    //and even do custom selections
    .select(function(rec) {
        return {
            fullname : rec.firstname + " " + rec.lastname,
            city : rec.location.city,
            ageInTenYears : (rec.age + 10)
        };
    });

C'est totalement extensible aussi!

La documentation est toujours en cours, mais vous pouvez toujours l'essayer en ligne.

46
Hugoware

Mise à jour: XQuery 3.1 peut interroger XML ou JSON - ou les deux simultanément. Et XPath 3.1 peut aussi.

La liste s'allonge:

33
Jonathan

jmespath fonctionne vraiment très facilement et bien, http://jmespath.org/ Il est utilisé par Amazon dans l'interface de ligne de commande AWS, il doit donc être relativement stable.

11
xor

La méthode intégrée array.filter() rend obsolètes la plupart de ces bibliothèques de requêtes javascript.

Vous pouvez définir autant de conditions que vous pouvez l'imaginer dans le délégué: comparaison simple, débutAvec, etc. Je n'ai pas testé, mais vous pouvez probablement aussi imbriquer des filtres pour interroger des collections internes.

8
Roger

ObjectPath est un langage de requête simple et léger pour les documents JSON de structure complexe ou inconnue. C'est semblable à XPath ou JSONPath, mais beaucoup plus puissant grâce aux calculs arithmétiques intégrés, aux mécanismes de comparaison et aux fonctions intégrées.

Example

La version Python est mature et utilisée en production. JS est toujours en version bêta.

Nous fournirons probablement dans un proche avenir une version Javascript complète. Nous souhaitons également le développer davantage afin qu’il puisse constituer une alternative plus simple aux requêtes Mongo.

7
Ela Bednarek

jq est un [~ # ~] j [~ # ~] SON q tout langage, principalement destiné à la ligne de commande mais avec des liaisons vers un large éventail de langages de programmation (Java, node.js, php, ...) et même disponible dans le navigateur via - jq-web .

Voici quelques illustrations basées sur la question initiale, qui donnait ce JSON à titre d'exemple:

 [{"x": 2, "y": 0}}, {"x": 3, "y": 1}, {"x": 4, "y": 1}]

SOMME (X) O Y> 0 (équivaudrait à 7)

map(select(.y > 0)) | add

LISTE (X) LORSQUE Y> 0 (équivaudrait à [3,4])

map(.y > 0)

la syntaxe jq étend la syntaxe JSON

Chaque expression JSON est une expression jq valide. Des expressions telles que [1, (1+1)] et {"a": (1 + 1)} `illustrent comment jq étend la syntaxe JSON.

Un exemple plus utile est l'expression jq:

{a,b}

qui, étant donné la valeur JSON {"a":1, "b":2, "c": 3}, est évalué à {"a":1, "b":2}.

7
peak

Si vous utilisez .NET, alors Json.NET prend en charge les requêtes LINQ par-dessus JSON. Ce post a quelques exemples. Il prend en charge le filtrage, la cartographie, le regroupement, etc.

6
James Newton-King

Une autre façon de voir cela serait d'utiliser mongoDB Vous pouvez stocker votre JSON dans mongo, puis l'interroger via la syntaxe de requête mongodb.

6
Alexx Roche

Voici quelques bibliothèques javascript simples qui feront également l'affaire:

  • Dollar Q est une bibliothèque légère de Nice. Il a une sensation familière à la syntaxe de chaînage rendue populaire par jQuery et n’est que 373 SLOC.
  • SpahQL est un langage de requête complet avec une syntaxe similaire à XPath ( Homepage , Github
  • jFunk est un langage de requête en cours, avec une syntaxe similaire à celle des sélecteurs CSS/jQuery. Cela semblait prometteur, mais aucun développement n’a été réalisé au-delà de son engagement initial.

  • (ajouté en 2014): le outil de ligne de commande jq a une syntaxe soignée, mais malheureusement, il s'agit d'une bibliothèque c. Exemple d'utilisation:

    < package.json jq '.dependencies | to_entries | .[] | select(.value | startswith("git")) | .key'

3
forivall

OK, cet article est un peu vieux, mais ... si vous voulez faire une requête de type SQL en JSON natif (ou objets JS) sur des objets JS, jetez un oeil à https://github.com/ deitch/searchjs

C'est à la fois un langage jsql écrit entièrement en JSON et une implémentation de référence. Vous pouvez dire: "Je souhaite rechercher tous les objets d'un tableau portant le nom ===" Jean "&& age === 25 ans, comme:

{name:"John",age:25,_join:"AND"}

L'implémentation de référence searchjs fonctionne dans le navigateur ainsi que comme paquet npm

npm install searchjs

Il peut également faire des choses comme les jointures complexes et la négation (PAS). Il ignore nativement le cas.

Il ne fait pas encore de sommation ou de comptage, mais il est probablement plus facile de faire celles de l'extérieur.

3
deitch

Dans MongoDB , voici comment cela fonctionnerait (dans le shell mongo, il existe des pilotes pour la langue de votre choix).

db.collection.insert({"x": 2, "y": 0}); // notice the ':' instead of ','
db.collection.insert({"x": 3, "y": 1});
db.collection.insert({"x": 4, "y": 1});

db.collection.aggregate([{$match: {"y": {$gt: 0}}}, 
                         {$group: {_id: "sum", sum: {$sum: "$x"}}}]);
db.collection.aggregate([{$match: {"y": {$gt: 0}}}, 
                         {$group: {_id: "list", list: {$Push: "$x"}}}]);

Les trois premières commandes insèrent les données dans votre collection. (Il suffit de démarrer le serveur mongod et de se connecter avec le client mongo.)

Les deux suivants traitent les données. $match filtres, $group applique respectivement sum et list.

3
serv-inc

SpahQL est, à ma connaissance, le plus prometteur et le plus réfléchi de ces projets. Je recommande fortement de le vérifier.

2
David
  1. Google a un projet appelé lovefield ; Je viens de le découvrir, et cela semble intéressant, bien que cela soit plus compliqué que de simplement glisser dans le soulignement ou le lodash.

    https://github.com/google/lovefield

Lovefield est un moteur de requête relationnel écrit en JavaScript pur. Il fournit également une aide pour la persistance des données côté navigateur, par exemple. utiliser IndexedDB pour stocker des données localement. Il fournit une syntaxe semblable à SQL et fonctionne avec plusieurs navigateurs (supporte actuellement Chrome 37+, Firefox 31+, = IE 10+, et Safari 5.1 + ...


  1. Une autre entrée récente intéressante dans cet espace appelée jinqJs .

    http://www.jinqjs.com/

    En examinant brièvement exemples , cela semble prometteur et le document API semble être bien écrit.


function isChild(row) {
  return (row.Age < 18 ? 'Yes' : 'No');
}

var people = [
  {Name: 'Jane', Age: 20, Location: 'Smithtown'},
  {Name: 'Ken', Age: 57, Location: 'Islip'},
  {Name: 'Tom', Age: 10, Location: 'Islip'}
];

var result = new jinqJs()
  .from(people)
  .orderBy('Age')
  .select([{field: 'Name'}, 
     {field: 'Age', text: 'Your Age'}, 
     {text: 'Is Child', value: isChild}]);

jinqJs est une petite bibliothèque javaScript simple, légère et extensible, sans dépendance. jinqJs fournit un moyen simple d'exécuter du SQL comme des requêtes sur des tableaux, des collections et des services Web JavaScript qui renvoient une réponse JSON. jinqJs est similaire à l'expression lambda de Microsoft pour .Net et offre des fonctionnalités similaires à celles des collections de requêtes utilisant une syntaxe et des fonctions de prédicat similaires à celles de SQL. jinqJs a pour objectif de fournir une expérience similaire à SQL aux programmeurs familiarisés avec les requêtes LINQ.

2
mg1075


Je viens de terminer une version libérable d’un JS-lib (defiant.js) côté client qui fait ce que vous recherchez. Avec defiant.js, vous pouvez interroger une structure JSON avec les expressions XPath que vous connaissez bien (aucune nouvelle expression de syntaxe comme dans JSONPath).

Exemple de fonctionnement (voir ici dans le navigateur http://defiantjs.com/defiant.js/demo/sum.avg.htm ):

var data = [
       { "x": 2, "y": 0 },
       { "x": 3, "y": 1 },
       { "x": 4, "y": 1 },
       { "x": 2, "y": 1 }
    ],
    res = JSON.search( data, '//*[ y > 0 ]' );

console.log( res.sum('x') );
// 9
console.log( res.avg('x') );
// 3
console.log( res.min('x') );
// 2
console.log( res.max('x') );
// 4

Comme vous pouvez le constater, DefiantJS étend l'objet global JSON avec une fonction de recherche et le tableau renvoyé est livré avec des fonctions d'agrégat. DefiantJS contient quelques autres fonctionnalités, mais celles-ci sont hors de portée pour ce sujet. Quiconque, vous pouvez tester la bibliothèque avec un évaluateur XPath côté client. Je pense que les personnes ne connaissant pas XPath trouveront cet évaluateur utile.
http://defiantjs.com/#xpath_evaluator

Plus d'informations sur defiant.js
http://defiantjs.com/
https://github.com/hbi99/defiant.js

J'espère que vous le trouverez utile ... Cordialement

2
Hakan Bilgin

Vous pouvez également utiliser nderscore.js , qui est essentiellement une bibliothèque swiss-knife pour manipuler des collections. En utilisant _.filter , _.pluck , _.reduce vous pouvez faire des requêtes de type SQL.

var data = [{"x": 2, "y": 0}, {"x": 3, "y": 1}, {"x": 4, "y": 1}];

var posData = _.filter(data, function(elt) { return elt.y > 0; });
// [{"x": 3, "y": 1}, {"x": 4, "y": 1}]

var values = _.pluck(posData, "x");
// [3, 4]

var sum = _.reduce(values, function(a, b) { return a+b; });
// 7

Underscore.js fonctionne à la fois côté client et côté serveur et est une bibliothèque remarquable.

Vous pouvez également utiliser Lo-Dash qui est un fork de Underscore.js avec de meilleures performances.

1
Michel Hua

Chaque fois que possible, je décalerais toutes les requêtes sur le serveur principal (sur la base de données SQL ou un autre type de base de données native). La raison en est qu’il sera plus rapide et plus optimisé de faire les requêtes.

Je sais que jSON peut être autonome et qu'il peut y avoir +/- pour avoir un langage d'interrogation, mais je ne vois pas l'avantage si vous récupérez des données du backend vers un navigateur, comme dans la plupart des cas d'utilisation de JSON. Interrogez et filtrez sur le serveur pour obtenir une donnée aussi petite que nécessaire.

Si pour une raison quelconque vous avez besoin d'interroger au front-end (principalement dans un navigateur), je suggérerais simplement d'utiliser array.filter (pourquoi inventer autre chose?).

Cela dit, ce qui serait plus utile, à mon avis, est une API de transformation pour JSON ... elles sont plus utiles, car une fois que vous avez les données, vous pouvez les afficher de différentes manières. Cependant, encore une fois, vous pouvez faire beaucoup de cela sur le serveur (ce qui peut être beaucoup plus facile à faire évoluer) que sur le client - SI vous utilisez un modèle de serveur <-> client.

Juste mes 2 pence vaut!

1
Colin Saxton

J'ajouterai à l'idée d'utiliser simplement votre propre javascript, mais pour quelque chose d'un peu plus sophistiqué, vous pouvez regarder données du dojo . Je ne l'ai pas utilisé, mais il semble que cela vous donne à peu près le type d'interface de requête que vous recherchez.

1
user65663

Départ https://github.com/niclasko/Cypher.js (note: je suis l'auteur)

Il s'agit d'une implémentation Javascript sans dépendance du langage de requête de la base de données de graphes Cypher avec une base de données de graphes. Il fonctionne dans le navigateur (testé avec Firefox, Chrome, IE).

Avec pertinence à la question. Il peut être utilisé pour interroger des points de terminaison JSON:

load json from "http://url/endpoint" as l return l limit 10

Voici un exemple d'interrogation d'un document JSON complexe et d'analyse sur celui-ci:

Exemple de requête JSON Cypher.js

0

Vous pouvez utiliser linq.js .

Cela permet d'utiliser des agrégations et des sélections à partir d'un ensemble d'objets, comme d'autres données de structures.

var data = [{ x: 2, y: 0 }, { x: 3, y: 1 }, { x: 4, y: 1 }];

// SUM(X) WHERE Y > 0     -> 7
console.log(Enumerable.From(data).Where("$.y > 0").Sum("$.x"));

// LIST(X) WHERE Y > 0    -> [3, 4]
console.log(Enumerable.From(data).Where("$.y > 0").Select("$.x").ToArray());
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
0
Nina Scholz