Question

Y at-il un (à peu près) SQL ou XQuery comme langage pour effectuer des requêtes JSON?

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

Comme exemple complètement maquillé, 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 cela fonctionnerait à la fois côté client et côté serveur avec des résultats convertis à la structure de données spécifique à la langue appropriée (ou peut-être conservés comme JSON)

Une recherche sur Google rapide suggère que les gens ont pensé et mis en œuvre un certain nombre de choses ( JAQL ), mais il ne semble pas comme un usage standard ou un ensemble de bibliothèques a encore émergé. Bien que chaque fonction est assez trivial à mettre en œuvre lui-même, si quelqu'un a déjà fait droit, je ne veux pas réinventer la roue.

Toutes les suggestions?

Edit: Cela peut en effet être une mauvaise idée ou JSON peut être un trop générique format pour ce que je pense .. La raison de vouloir un langage de requête au lieu de simplement faire le sommateur / fonctions etc directement au besoin est que je l'espoir de construire des requêtes dynamiquement en fonction d'entrée utilisateur. Un peu comme l'argument selon lequel « on n'a pas besoin de SQL, nous pouvons simplement écrire les fonctions dont nous avons besoin ». Finalement, que ce soit sort de la main ou vous finissez par écrire votre propre version de SQL que vous poussez plus loin et plus loin. (D'accord, je sais que c'est un peu un argument stupide, mais vous voyez l'idée ..)

Était-ce utile?

La solution

Bien sûr, que diriez-vous:

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

EDIT Sep-2015: En fait, il est maintenant JSON pointeur standard qui permet traversal très simple et efficace du contenu JSON. Il est non seulement formellement spécifié, mais également soutenu par de nombreuses bibliothèques JSON. Donc, je l'appellerais réelle norme utile réelle, bien qu'en raison de son expressivité limitée, il peut ou ne peut pas être considéré comme langage de requête en soi.

Autres conseils

Je recommande mon projet, je travaille sur appelé jLinq. Je cherche des commentaires si je serais intéressé à entendre ce que vous pensez.

Si vous permet d'écrire des requêtes similaires à la façon dont vous le feriez dans 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)
        };
    });

Il est entièrement extensible trop!

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

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

La liste est en croissance:

jmespath fonctionne vraiment très facile et bien, http://jmespath.org/ Il est utilisé par Amazon dans l'interface de ligne de commande AWS, ce qui procure un a tout à fait stable.

Le méthode array.filter() fait la plupart des ces soi-disant javascript bibliothèques de requête obsolète

Vous pouvez mettre autant de conditions à l'intérieur du délégué que vous pouvez imaginer: simple comparaison, startsWith, etc. Je ne l'ai pas testé, mais vous pourriez probablement des filtres nid aussi pour effectuer des requêtes internes collections

.

ObjectPath est langage de requête simple et ligthweigth pour les documents JSON de structure complexe ou inconnue. Il est similaire à XPath ou JSONPath, mais beaucoup plus puissant grâce à des calculs arithmétiques intégrés, des mécanismes de comparaison et fonctions intégrées.

Exemple

version Python est mature et utilisé dans la production. JS est encore en version bêta.

Probablement dans un proche avenir, nous fournirons une version Javascript à part entière. Nous voulons aussi développer davantage, afin qu'il puisse servir d'alternative simple aux requêtes mongo.

jq est un J SON q langue uery, principalement destinés à la ligne de commande, mais avec des liaisons à un large éventail de langages de programmation (Java, Node.js, php, ...) et même disponible dans le navigateur via JQ-web .

Voici quelques illustrations en fonction de la question initiale, qui a donné cette JSON comme exemple:

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

SUM (X) dans laquelle Y> 0 (équivaudrait à 7)

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

LIST (X) dans laquelle Y> 0 (équivaudrait à [3,4])

map(.y > 0)

Syntaxe de JQ étend la syntaxe JSON

Chaque expression JSON est une expression valide, et 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 de JQ:

{a,b}

qui, compte tenu de la valeur de {"a":1, "b":2, "c": 3} JSON, évalue à {"a":1, "b":2}.

Si vous utilisez .NET puis Json.NET supporte les requêtes LINQ sur haut de JSON. Cette post a quelques exemples. Il prend en charge le filtrage, la cartographie, le regroupement, etc.

Une autre façon de regarder ce serait d'utiliser MongoDB Vous peut stocker votre JSON dans mongo puis interroger via la syntaxe de requête MongoDB.

OK, ce poste est un peu vieux, mais ... si vous voulez faire des demandes, comme SQL JSON natif (ou objets JS) sur les objets JS, jetez un oeil à https://github.com/deitch/searchjs

Il est à la fois un langage de jsql entièrement écrit en JSON, et une implémentation de référence. Vous pouvez dire: « Je veux trouver tous les objets dans un tableau qui ont nom === » John » && âge === 25 comme:

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

Les travaux de mise en œuvre de référence dans le navigateur, ainsi que comme un ensemble de NPM de noeud

npm install searchjs

Il peut aussi faire des choses comme de jointures complexes et négation (NOT). Il ne tient pas compte nativement le cas.

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

Voici quelques simples bibliothèques javascript qui va aussi faire l'affaire:

  • Dollar Q est une belle bibliothèque légère. Il a une sensation familière à la syntaxe Enchaînement rendu populaire par jQuery et est seulement 373 SLOC.
  • SpahQL est un langage de requête riche en fonctionnalités avec une syntaxe similaire à XPath ( Page d'accueil , Github
  • jfunk est en cours langage de requête, avec une syntaxe similaire à CSS / sélecteurs jQuery. Il semblait prometteur, mais n'a pas eu de développement au-delà de son en première commettras.

  • (ajouté 2014): l'outil de ligne de commande jq a une syntaxe propre, mais malheureusement, il est une bibliothèque alternative. Exemple d'utilisation:

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

MongoDB , voilà comment cela fonctionnerait (dans le shell mongo, il existe des pilotes pour une 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érer les données dans votre collection. (Il suffit de démarrer le serveur mongod et se connecter avec le client mongo.)

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

SpahQL est le plus prometteur et bien pensé de ceux-ci, pour autant que je peux dire. Je recommande fortement vérifier.


Je viens de terminer une version libérables d'un JS-lib clientside (defiant.js) qui fait ce que vous cherchez. Avec defiant.js, vous pouvez interroger une structure JSON avec les expressions XPath que vous connaissez (pas de nouvelles expressions de syntaxe comme dans JSONPath).

Exemple de la façon dont il fonctionne (voir dans le navigateur ici 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 voir, DefiantJS étend la JSON globale de l'objet avec une fonction de recherche et le tableau retourné est livré avec des fonctions d'agrégation. DefiantJS contient quelques autres fonctionnalités, mais ceux-ci sont hors de la portée de ce sujet. Anywho, vous pouvez tester le répertoire lib avec un clientside XPath Evaluator. Je pense que les gens ne sont pas familiers avec 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 qu'elle vous sera utile ... Cordialement

  1. Google a un projet appelé lovefield ; vient de découvrir à son sujet, et il semble intéressant, mais il est plus impliqué que juste laisser tomber dans underscore ou lodash.

    https://github.com/google/lovefield

  

Lovefield est un moteur de requête relationnelle écrit en JavaScript pur. Il   fournit également de l'aide des données qui persistent sur le côté du navigateur, par exemple   en utilisant IndexedDB pour stocker des données localement. Il fournit des syntaxe de type SQL   fonctionne multi-navigateur (supportant actuellement Chrome 37+, 31+ Firefox, IE   10+ et Safari 5.1 + ...


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

    http://www.jinqjs.com/

    En bref examen de la , il semble prometteur, et document API semble 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 un petit, simple, léger et extensible javaScript   bibliothèque qui n'a pas de dépendances. jinqJs fournit un moyen simple de   effectuer des requêtes sur SQL comme des tableaux, des collections et JAVASCRIPT web   services qui renvoient une réponse JSON. jinqJs est similaire à Microsoft   expression Lambda pour .Net, et il offre des fonctionnalités similaires à   collections de requête SQL en utilisant une syntaxe et la fonctionnalité comme prédicat.   Le but de jinqJs est de fournir une expérience SQL comme aux programmeurs   familier avec les requêtes LINQ.

Je vais seconde l'idée d'utiliser simplement votre javascript, mais pour quelque chose d'un peu plus sophistiqué, vous pouvez regarder données dojo . Je n'ai pas utilisé, mais il semble que ça vous donne à peu près le type d'interface de requête que vous cherchez.

Les objectifs de mise en œuvre en cours Jaql grand traitement de données en utilisant un cluster Hadoop, il est peut-être plus que vous avez besoin. Cependant, il fonctionne facilement sans un cluster Hadoop (mais nécessite toujours le code Hadoop et ses dépendances pour obtenir compilés, qui sont pour la plupart inclus). Une petite mise en œuvre de Jaql qui pourrait être intégré dans Javascript et un navigateur serait un excellent ajout au projet.

Vos exemples ci-dessus sont écrits facilement en jaql:

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

$data -> filter $.y > 0 -> transform $.x -> sum(); // 7

$data -> filter $.y > 0 -> transform $.x; // [3,4]

Bien sûr, il y a beaucoup plus aussi. Par exemple:

// Compute multiple aggregates and change nesting structure:
$data -> group by $y = $.y into { $y, s:sum($[*].x), n:count($), xs:$[*].x}; 
    // [{ "y": 0, "s": 2, "n": 1, "xs": [2]   },
    //  { "y": 1, "s": 7, "n": 2, "xs": [3,4] }]

// Join multiple data sets:
$more = [{ "y": 0, "z": 5 }, { "y": 1, "z": 6 }];
join $data, $more where $data.y == $more.y into {$data, $more};
    // [{ "data": { "x": 2, "y": 0 }, "more": { "y": 0, "z": 5 }},
    //  { "data": { "x": 3, "y": 1 }, "more": { "y": 1, "z": 6 }},
    //  { "data": { "x": 4, "y": 1 }, "more": { "y": 1, "z": 6 }}]

Jaql peut être téléchargé / discuté http://code.google.com/p/jaql /

Vous pouvez également utiliser Underscore.js qui est essentiellement une bibliothèque couteau suisse pour manipuler des collections. En utilisant _.filter , _.pluck , _.reduce vous pouvez faire des requêtes 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 une fourchette de Underscore.js avec de meilleures performances.

Chaque fois que possible, je déplacerait tous l'interrogation au back-end sur le serveur (à la base de données SQL ou un autre type de base de données native). La raison en est que ce sera plus rapide et plus optimisé pour faire exécuter des requêtes.

Je sais que JSON peut être autonome et il peut être +/- pour avoir un langage d'interrogation, mais je ne vois pas l'avantage si vous récupérez des données à partir du back-end à un navigateur, comme la plupart des cas d'utilisation de JSON. Requête et filtre au back-end pour obtenir des données aussi petit que nécessaire.

Si pour une raison quelconque, vous devez interroger à la fin avant (la plupart du temps dans un navigateur) alors je suggère que l'utilisation Array.filter (pourquoi inventer autre chose?).

Cela dit ce que je pense serait plus utile est une API de transformation pour JSON ... ils sont plus utiles car une fois que vous avez les données que vous pouvez afficher dans un certain nombre de façons. Cependant, encore une fois, vous pouvez faire beaucoup de cela sur le serveur (qui peut être beaucoup plus facile à l'échelle) que sur le client - Si vous utilisez le serveur <->. Modèle client

Juste mes 2 pence valeur!

Consultez https://github.com/niclasko/Cypher.js (note : Je suis l'auteur)

Il est un de la langue de requête de base de données graphique Cypher mise en œuvre Javascript zéro de dépendance avec une base de données de graphique. Il fonctionne dans le navigateur (testé avec Firefox, Chrome, IE).

Avec la pertinence à la question. Il peut être utilisé pour interroger points d'extrémité JSON:

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

Voici un exemple d'interroger un document JSON complexe et effectuer des analyses sur elle:

Cypher.js JSON exemple de requête

Vous pouvez utiliser linq.js .

Ceci permet d'utiliser agrégations et selectings à partir d'un ensemble de données d'objets, d'autres structures de données.

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>

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top