Domanda

C'è un (circa) SQL o XQuery-come linguaggio per l'interrogazione di JSON?

Sto pensando di set di dati molto piccoli che mappa ben JSON dove sarebbe bello poter facilmente rispondere a domande come "quali sono tutti i valori di X, dove Y > 3" o di fare le solite SOMMA / tipo di CONTEGGIO operazioni.

Come completamente inventati esempio, qualcosa di simile a questo:

[{"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])

Sto pensando che questo avrebbe funzionato sia client-side e server-side con i risultati di essere convertiti per la specifica del linguaggio struttura di dati (o forse mantenuto quanto JSON)

Una rapida ricerca con Google suggerisce che le persone che hanno pensato e realizzato un paio di cose (JAQL), ma non mi sembrano un utilizzo standard o un set di librerie è emerso sicurezza.Mentre ogni funzione è abbastanza banale da implementare, ma se qualcuno lo ha già fatto a destra non ho voglia di re-inventare la ruota.

Qualche suggerimento?

Edit:Questo può effettivamente essere una cattiva idea o JSON può essere troppo generico, un formato per quello che ho in mente..Il motivo per desiderare un linguaggio di query, invece di fare la somma di/etc direttamente le funzioni necessarie è che ho la speranza di costruire la query dinamicamente sulla base di input dell'utente.Un po ' come l'argomento che "non abbiamo bisogno di SQL, si può semplicemente scrivere le funzioni di cui abbiamo bisogno".Alla fine, che sia sfugga di mano o si finisce di scrivere la propria versione di SQL come lo spingere di più.(Okay, so che è un po ' sciocco argomento, ma si ottiene l'idea..)

È stato utile?

Soluzione

Certo, come su:

Tutti sembrano essere un po 'di lavoro in corso, ma lavorare in una certa misura. Essi sono simili a XPath e XQuery concettualmente; anche se XML e JSON hanno diversi modelli concettuali (gerarchici vs oggetto / struct).

Modifica Set-2015: In realtà non v'è ora JSON Pointer standard che consente l'attraversamento molto semplice ed efficiente dei contenuti JSON. Non è solo formalmente specificato, ma sostenuto anche da molte biblioteche JSON. Quindi mi sento di chiamarlo attuale standard di utile reale, anche se a causa della sua espressività limitata che può o non può essere considerato Query Language per sé.

Altri suggerimenti

mi consiglia il mio progetto su cui sto lavorando chiamato jLinq . Sto cercando le risposte in modo sarei interessato a sentire cosa ne pensate.

Se vi permette di scrivere query simili a come si farebbe in 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)
        };
    });

E 'completamente estensibile troppo!

La documentazione è ancora in corso, ma è ancora possibile provare on-line.

Aggiornamento: XQuery 3.1 può interrogare XML o JSON - o entrambe insieme. E XPath 3.1 può troppo.

La lista è in crescita:

jmespath funziona davvero molto semplice e ben, http://jmespath.org/ Esso è utilizzato da Amazon nell'interfaccia a riga di comando AWS, in modo E'avuto modo di essere abbastanza stabile.

Il built-in array.filter() metodo rende la maggior parte di questi cosiddetti javascript librerie query obsoleti

Si può mettere come molte condizioni all'interno del delegato, come si può immaginare:semplice confronto, startsWith, etc.Non ho testato ma probabilmente si potrebbe nido filtri troppo per l'esecuzione di query interna collezioni.

ObjectPath è un linguaggio semplice e ligthweigth query per i documenti JSON di struttura complessa o sconosciuto. E 'simile a XPath o JSONPath, ma molto più potente grazie a calcoli aritmetici embedded, i meccanismi di confronto e funzioni built-in.

Esempio

versione di Python è maturo e utilizzato nella produzione. JS è ancora in beta.

Probabilmente nel prossimo futuro ci fornirà una versione completa a tutti gli effetti Javascript. Vogliamo anche svilupparlo ulteriormente, in modo che potesse servire come una semplice alternativa alle query Mongo.

JQ è un J SON q lingua uery, principalmente destinati alla riga di comando, ma con attacchi ad una vasta gamma di linguaggi di programmazione (Java, Node.js, PHP, ...) e anche disponibili nel browser tramite JQ-web .

Ecco alcune illustrazioni in base alla domanda iniziale, che ha dato questa JSON come esempio:

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

SUM (X) dove y> 0 (sarebbe pari a 7)

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

LIST (X) dove y> 0 (sarebbe pari a [3,4])

map(.y > 0)

sintassi JQ estende JSON sintassi

Ogni espressione JSON è espressione di una valida JQ, e espressioni come [1, (1+1)] e { "a": (1 + 1)}. `Illustrare come JQ si estende la sintassi JSON

Un esempio più utile è l'espressione JQ:

{a,b}

che, dato il valore {"a":1, "b":2, "c": 3} JSON, restituisce {"a":1, "b":2}.

Se si utilizza .NET quindi Json.NET supporta LINQ interroga su la parte superiore di JSON. Questo posta ha qualche esempio. Supporta il filtraggio, la mappatura, il raggruppamento, ecc.

Un altro modo di guardare a questo sarebbe quella di utilizzare MongoDB È in grado di memorizzare il vostro JSON in mongo e poi interrogare tramite la sintassi di query MongoDB.

OK, questo post è un po 'vecchio, ma ... se si vuole fare query SQL-like in JSON nativo (o oggetti JS) su oggetti JS, dare un'occhiata a https://github.com/deitch/searchjs

E 'sia una lingua jsql scritto interamente in JSON, e un'implementazione di riferimento. Si può dire: "Voglio trovare tutti gli oggetti in una matrice che ha nome ===" John" && età === 25 come:

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

opere l'implementazione di riferimento searchjs nel browser, nonché come pacchetto npm nodo

npm install searchjs

Si può anche fare cose come complesso unisce e negazione (NOT). Si ignora nativamente caso.

Non ha ancora fare sommatoria o contare, ma è probabilmente più facile da fare quelli di fuori.

Ecco alcuni semplici librerie JavaScript che anche fare il trucco:

MongoDB driver , questo è come avrebbe funzionato (nella shell mongo, esistono per una lingua a vostra scelta).

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"}}}]);

I primi tre comandi inserire i dati nella tua collezione. (Basta avviare il server mongod e connettersi con il cliente mongo.)

Il prossimo due elaborare i dati. $match filtri, $group applica il sum e list, rispettivamente.

SpahQL è la più promettente e ben pensato di questi, per quanto posso dire. Consiglio vivamente il check-out.


Ho appena finito una versione rilasciabile di un lato client JS-lib (defiant.js) che fa quello che stai cercando. Con defiant.js, è possibile interrogare una struttura JSON con le espressioni XPath si ha familiarità con (no nuove espressioni di sintassi come in JSONPath).

Esempio di come funziona (vedi nel browser here 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

Come si può vedere, DefiantJS estende l'JSON oggetto globale con una funzione di ricerca e la matrice restituita viene consegnata con funzioni di aggregazione. DefiantJS contiene alcune altre funzionalità, ma quelli sono fuori del campo di applicazione per questo argomento. Anywho, è possibile verificare la lib con un clientside XPath Evaluator. Penso che le persone che non hanno familiarità con XPath troveranno questo valutatore utile.
http://defiantjs.com/#xpath_evaluator

Maggiori informazioni su defiant.js
http://defiantjs.com/
https://github.com/hbi99/defiant.js

Spero vi sia utile ... Saluti

  1. Google ha un progetto chiamato Lovefield ; appena scoperto che su di esso, e sembra interessante, anche se è più coinvolto non solo cadere nella sottolineatura o lodash.

    https://github.com/google/lovefield

  

Lovefield è un motore di query relazionale scritto in puro JavaScript. esso   fornisce anche aiuto con dati persistenti sul lato del browser, ad esempio,   utilizzando IndexedDB per memorizzare i dati localmente. Fornisce sintassi SQL-like e   funziona cross-browser (attualmente sostenendo Chrome 37+, 31+ Firefox, IE   10+, e Safari 5.1 + ...


  1. Un altro recente ingresso interessante in questo spazio chiamato jinqJs .

    http://www.jinqjs.com/

    In breve la , sembra promettente, e la documento API sembra essere ben scritto.


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 è un piccolo, semplice, leggero ed estensibile javaScript   libreria che non ha dipendenze. jinqJs fornisce un modo semplice per   eseguire SQL come query su array JavaScript, collezioni e web   servizi che restituiscono una risposta JSON. jinqJs è simile a Microsoft   espressione lambda per .Net, e fornisce funzionalità simili a   collezioni di query che utilizzano uno SQL come sintassi e funzionalità predicato.   Lo scopo di jinqJs è quello di fornire uno SQL come esperienza per i programmatori   familiarità con le query LINQ.

io secondo la nozione di usando solo il tuo proprio javascript, ma per qualcosa di un po 'più sofisticato si potrebbe guardare a dati dojo . Non ho usato, ma sembra che ti dà più o meno il tipo di interfaccia di query che stai cercando.

Il attuali obiettivi di attuazione Jaql elaborazione dati di grandi dimensioni utilizzando un cluster Hadoop, quindi potrebbe essere più del necessario. Tuttavia, viene eseguito facilmente senza un cluster Hadoop (ma richiede ancora il codice Hadoop e le sue dipendenze per ottenere compilati, che sono per lo più compresi). Una piccola implementazione di Jaql che potrebbe essere incorporato in Javascript e un browser sarebbe una grande aggiunta al progetto.

I tuoi esempi di cui sopra sono facilmente scritti in 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]

Naturalmente, c'è molto di più anche. Ad esempio:

// 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 può essere scaricato / discussa in http://code.google.com/p/jaql /

È inoltre possibile utilizzare Underscore.js che è fondamentalmente una libreria swiss-knife per manipolare le collezioni. Utilizzando _.filter , _.pluck , _.reduce si può fare query SQL-like.

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 funziona sia sul lato client e lato server ed è una libreria notevole.

È inoltre possibile utilizzare Lo-Dash che è un fork di Underscore.js con prestazioni migliori.

Quando possibile vorrei spostare tutto l'interrogazione al backend sul server (al DB SQL o un altro tipo di database nativo). Motivo è che sarà più veloce e più ottimizzato per fare l'interrogazione.

So che JSON può essere stand-alone e non ci possono essere +/- per avere un linguaggio di query, ma non riesco a vedere il vantaggio se si stanno recuperando i dati dal back-end per un browser, come la maggior parte dei casi d'uso JSON. Query e filtro al back-end per ottenere un dato il più piccolo che è necessario.

Se per qualsiasi motivo è necessario interrogare al front-end (per lo più in un browser) poi vorrei suggerire usando solo Array.filter (perché inventare qualcos'altro?).

Detto questo quello che penso sarebbe più utile è un'API di trasformazione per JSON ... sono più utile, perché una volta che hai i dati si può decidere di visualizzare in un certo numero di modi. Tuttavia, ancora una volta, si può fare molto di questo sul server (che può essere molto più facile da scalare) che sul client - se si utilizza server <->. Modello client

A soli i miei 2 centesimi vale la pena!

https://github.com/niclasko/Cypher.js (nota : sono l'autore)

Si tratta di un'implementazione zero dipendenza Javascript del linguaggio di interrogazione database grafico Cypher insieme a un database grafico. Esso viene eseguito nel browser (testato con Firefox, Chrome, IE).

Con rilevanza per la questione. Può essere usato per interrogare gli endpoint JSON:

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

Ecco un esempio di interrogazione di un documento JSON complessa e l'esecuzione di analisi su di esso:

Cypher.js JSON esempio di query

Si potrebbe utilizzare linq.js .

Questo permette di utilizzare aggregazioni e selectings da un insieme di dati di oggetti, come dati altre strutture.

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>

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top