Pergunta

Existe uma (aproximadamente) SQL ou XQuery-como linguagem para consultar JSON?

Estou pensando muito pequenos conjuntos de dados que mapeiam bem para JSON onde seria bom para facilmente responder a perguntas como "o que são todos os valores de X onde Y> 3" ou para fazer as operações habituais SUM / tipo de COUNT .

exemplo Como completamente inventada, algo como isto:

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

Eu estou pensando que isso iria trabalhar tanto do lado do cliente e do lado do servidor com resultados que estão sendo convertidos para a estrutura de dados específicos do idioma apropriado (ou talvez mantido como JSON)

Uma rápida Googling sugere que as pessoas têm pensado sobre isso e implementou algumas coisas ( JAQL ), mas não parece ser um uso padrão ou conjunto de bibliotecas ainda não surgiu. Enquanto cada função é bastante trivial para implementar por conta própria, se alguém já fez isso certo Eu não quero re-inventar a roda.

Todas as sugestões?

Edit: Isso pode realmente ser uma má idéia ou JSON pode ser formato de um genérico demais para o que eu estou pensando .. A razão para querer uma linguagem de consulta em vez de apenas fazer a soma / etc funções diretamente como necessário é que eu esperamos construir as consultas dinamicamente com base em user-entrada. Kinda como o argumento de que "não precisamos de SQL, podemos apenas escrever as funções que precisamos". Eventualmente que ou fica fora de mão ou você acaba escrevendo sua própria versão do SQL como você empurrá-lo mais e mais. (Ok, eu sei que é um pouco de um argumento bobo, mas você começa a idéia ..)

Foi útil?

Solução

Claro, como sobre: ??

Eles todos parecem ser uma obra pouco em andamento, mas o trabalho em algum grau. Eles também são semelhantes aos XPath e XQuery conceitualmente; embora XML e JSON têm diferentes modelos conceituais (hierárquicos vs objeto / struct).

Editar Sep-2015: Na verdade há agora JSON Pointer padrão que permite travessia muito simples e eficiente dos conteúdos JSON. Ele não só é especificado formalmente, mas também apoiada por muitas bibliotecas JSON. Então, eu diria que é real padrão real útil, embora devido à sua expressividade limitada que pode ou não ser considerado Query Language per se.

Outras dicas

eu recomendo o meu projeto que estou trabalhando no chamado jLinq . Estou à procura de feedback para que eu estaria interessado em ouvir o que você pensa.

Se lhe permite escrever consultas semelhantes a como você faria em 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)
        };
    });

É totalmente extensível também!

A documentação ainda está em andamento, mas ainda é possível experimentá-lo on-line.

Update: XQuery 3.1 pode consultar XML ou JSON - ou os dois juntos. E XPath 3.1 também pode.

A lista está crescendo:

jmespath funciona realmente muito fácil e bem, http://jmespath.org/ Ele está sendo usado pela Amazon na interface de linha de comando AWS, por isso é preciso ser bastante estável.

A built-in array.filter() método faz a maioria dos estes chamados bibliotecas de consulta javascript obsoleto

Você pode colocar quantos condições dentro do delegado como você pode imaginar: simples comparação, startsWith, etc. Eu não testei, mas você poderia provavelmente filtros ninho também para consultar coleções internas

.

ObjectPath é simples e ligthweigth linguagem de consulta para documentos JSON de estrutura complexa ou desconhecida. É semelhante ao XPath ou JSONPath, mas muito mais poderosos graças aos cálculos aritméticos embutidos, mecanismos de comparação e funções embutidas.

Exemplo

versão Python é maduro e utilizados na produção. JS ainda está em beta.

Provavelmente no futuro próximo iremos fornecer uma versão de pleno direito Javascript. Nós também queremos desenvolvê-la, para que ele poderia servir como uma alternativa mais simples para consultas Mongo.

jq é um J SON q linguagem uery, destina-se principalmente para a linha de comando, mas com ligações a uma ampla gama de linguagens de programação (Java, node.js, php, ...) e até mesmo disponível no navegador via jq-web .

Aqui estão algumas ilustrações com base na pergunta original, que deu esta JSON como um exemplo:

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

SUM (X) em que Y> 0 (equivaleria a 7)

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

LISTA (X) em que Y> 0 (equivaleria a [3,4])

map(.y > 0)

jq sintaxe estende JSON sintaxe

expressão Cada JSON é uma expressão jq válido, e expressões como [1, (1+1)] e { "a": (1 + 1)}. `Ilustrar como jq estende sintaxe JSON

Um exemplo mais útil é a expressão jq:

{a,b}

que, dado o valor {"a":1, "b":2, "c": 3} JSON, avaliada como {"a":1, "b":2}.

Se você estiver usando .NET então Json.NET suporta LINQ consulta sobre o topo da JSON. Este pós tem alguns exemplos. Ele suporta filtragem, mapeamento, agrupamento, etc.

Outra maneira de olhar para isso seria usar mongoDB Você pode guardar a sua JSON em mongo e depois consultá-lo através da sintaxe de consulta do MongoDB.

OK, este post é um pouco velho, mas ... se você quer fazer SQL-like consulta no JSON nativa (ou JS objetos) em objetos JS, dar uma olhada em https://github.com/deitch/searchjs

É tanto uma linguagem jsql escrito inteiramente em JSON, e uma implementação de referência. Você pode dizer: "Eu quero encontrar todos os objetos em uma matriz que tem o nome ===" John" && idade === 25 como:

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

A implementação de referência searchjs obras no navegador, bem como como um pacote nó npm

npm install searchjs

Ele também pode fazer coisas como junções complexas e negação (NOT). Nativamente ignora caso.

Ele não ainda fazer somatório ou contar, mas é provavelmente mais fácil de fazer aqueles que estão fora.

Aqui estão algumas bibliotecas javascript simples que também irá fazer o truque:

  • Dollar Q é uma biblioteca leve agradável. Ele tem uma sensação familiar para a sintaxe encadeamento tornou popular por jQuery e está a apenas 373 SLOC.
  • SpahQL é uma linguagem de consulta inteiramente caracterizado com uma sintaxe semelhante ao XPath ( Página , github
  • Jfunk é uma em andamento linguagem de consulta, com uma sintaxe semelhante ao CSS / selectores jQuery. Parecia promissor, mas não teve qualquer desenvolvimento para além da sua no commit inicial.

  • (adicionado 2014): o jq ferramenta de linha de comando tem uma sintaxe limpa, mas infelizmente, é biblioteca ac. Exemplo de utilização:

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

Na MongoDB , este é como ele iria trabalhar (no shell mongo, existem controladores para uma linguagem de sua escolha).

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

Os três primeiros comandos inserir os dados na sua coleção. (Basta iniciar o servidor mongod e se conectar com o cliente mongo.)

O próximo dois processar os dados. $match filtros, $group aplica o sum e list, respectivamente.

SpahQL é a mais promissora e bem pensado destes, tanto quanto eu posso dizer. Eu recomendo verificar-se.


Acabei de terminar uma versão releaseable de um clientside JS-lib (defiant.js) que faz o que você está procurando. Com defiant.js, você pode consultar uma estrutura JSON com as expressões XPath você está familiarizado com (sem novas expressões de sintaxe, como no JSONPath).

Exemplo de como ele funciona (vê-lo no navegador aqui 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

Como você pode ver, DefiantJS estende o JSON objeto global com uma função de pesquisa e a matriz retornada é entregue com funções de agregação. DefiantJS contém algumas outras funcionalidades, mas aqueles estão fora do escopo deste assunto. Anywho, você pode testar o lib com uma clientside XPath Evaluator. Acho que as pessoas não familiarizadas com XPath vai encontrar este avaliador útil.
http://defiantjs.com/#xpath_evaluator

Mais informações sobre defiant.js
http://defiantjs.com/
https://github.com/hbi99/defiant.js

Espero que seja útil ... Saudações

  1. O Google tem um projeto chamado Lovefield ; só descobri sobre isso, e parece interessante, embora seja mais envolvido do que apenas caindo em sublinhado ou lodash.

    https://github.com/google/lovefield

Lovefield é um mecanismo de consulta relacional escrito em puro JavaScript. isto também fornece ajuda com persistência de dados no lado do navegador, v.g. usando IndexedDB para armazenar dados localmente. Ele fornece SQL-como sintaxe e funciona cross-browser (actualmente a apoiar Chrome 37+, 31+ Firefox, IE 10+, e Safari 5.1 + ...


  1. Outra recente entrada interessante neste espaço chamado jinqJs .

    http://www.jinqjs.com/

    Resumidamente rever a exemplos , parece promissor, e documento API parece ser bem escrito.


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 é um pequeno, simples, leve e extensível javaScript biblioteca que não tem dependências. jinqJs fornece uma maneira simples de executar SQL como consultas em matrizes de JavaScript, coleções e web serviços que retornam uma resposta JSON. jinqJs é semelhante ao da Microsoft expressão lambda para .Net, e fornece recursos semelhantes aos coleções de consulta usando um SQL como a sintaxe e funcionalidade predicado. O propósito de jinqJs é fornecer um SQL como experiência para programadores familiarizado com consultas LINQ.

Eu vou segunda a noção de apenas usando seu próprio javascript, mas para algo um pouco mais sofisticado que você pode olhar para dojo dados . Não usei, mas parece que ele dá-lhe mais ou menos o tipo de consulta interface que você está procurando.

As metas atuais de implementação Jaql grandes de processamento de dados usando um cluster Hadoop, por isso pode ser mais do que precisa. No entanto, corre-se facilmente sem um cluster Hadoop (mas ainda requer o código Hadoop e suas dependências para se compilados, que são na sua maioria incluídas). Uma pequena implementação de Jaql que poderia ser incorporado em Javascript e um navegador seria uma grande adição ao projeto.

Seus exemplos acima são facilmente escritos em 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]

É claro que há muito mais também. Por exemplo:

// 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 pode ser baixado / discutido em http://code.google.com/p/jaql /

Você também pode usar Underscore.js que é basicamente uma biblioteca swiss-faca para manipular coleções. Usando _.filter , _.pluck , _.reduce você pode fazer SQL-como consultas.

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 funciona tanto do lado do cliente e do lado do servidor e é uma biblioteca notável.

Você também pode usar Lo-traço que é um fork do Underscore.js com melhores performances.

Sempre que possível eu iria mudar toda a consulta para o servidor no servidor (para o SQL DB ou outro tipo de banco de dados nativo). Razão de ser é que ele vai ser mais rápido e mais otimizado para fazer a consulta.

Eu sei que JSON pode ser ficar sozinho e pode haver +/- por ter uma linguagem de consulta, mas não consigo ver a vantagem se você está recuperando dados do backend para um navegador, como a maioria dos casos de uso de JSON. Consulta e filtro no backend para obter como dados uma pequena que é necessário.

Se por qualquer motivo você precisa para consulta no front-end (principalmente em um navegador), então eu sugiro apenas usando array.filter (por que inventar outra coisa?).

Dito isso que eu acho que seria mais útil é uma API de transformação para json ... eles são mais útil, pois uma vez que você tem os dados que você pode querer exibi-lo em uma série de maneiras. No entanto, mais uma vez, você pode fazer muito deste no servidor (que pode ser muito mais fácil de escala) do que no cliente - Se você estiver usando servidor <->. Modelo cliente

Apenas meu valor 2 pence!

Confira https://github.com/niclasko/Cypher.js (nota : Eu sou o autor)

É uma dependência de zero Javascript implementação da linguagem de consulta de banco de dados gráfico Cypher, juntamente com um banco de dados gráfico. Ele é executado no navegador (testado com Firefox, Chrome, IE).

Com relevância para a questão. Ele pode ser usado para endpoints JSON consulta:

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

Aqui está um exemplo de consultar um documento JSON complexa e realização de análises sobre ele:

Cypher.js JSON exemplo consulta

Você pode usar linq.js .

Isso permite usar agregações e selectings a partir de um conjunto de dados de objetos, como dados de outras estruturas.

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>

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top