是否有JSON的查询语言?

时间:2009-04-22 14:21:43

标签: json nosql web-standards querying dynamic-queries

是否有用于查询JSON的(大致)SQL或类XQuery语言?

我正在考虑非常小的数据集,这些数据集很好地映射到JSON,很容易回答查询,例如“X的所有值是什么,其中Y> 3”或执行通常的SUM / COUNT类型操作

作为完全构成的例子,像这样:

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

我认为这可以在客户端和服务器端工作,结果转换为适当的特定于语言的数据结构(或者可能保存为JSON)

快速谷歌搜索表明人们已经考虑过它并实现了一些东西(JAQL),但它似乎还没有出现标准用法或一组库。虽然每个功能都可以自行实现,但如果有人已经做好了,我不想重新发明轮子。

有什么建议吗?

编辑:这可能确实是一个坏主意,或者JSON对于我正在思考的内容可能过于通用。想要查询语言而不是直接根据需要直接执行求和/等功能的原因是我希望根据用户输入动态构建查询。有点像“我们不需要SQL,我们只能编写我们需要的功能”的论点。最终要么失控,要么在你进一步推动时最终编写自己的SQL版本。 (好吧,我知道这是一个有点愚蠢的论点,但你明白了。)

23 个答案:

答案 0 :(得分:80)

当然,怎么样:

它们似乎都在进行中,但在某种程度上有效。它们在概念上也类似于XPath和XQuery;即使XML和JSON具有不同的概念模型(层次结构与对象/结构)。

编辑 2015年9月:实际上现在有JSON Pointer标准允许非常简单有效地遍历JSON内容。它不仅是正式指定的,而且还受到许多JSON库的支持。所以我称之为实际真正有用的标准,尽管由于其表达能力有限,它可能会或可能不会被视为查询语言本身。

答案 1 :(得分:46)

I'd recommend my project I'm working on called jLinq。我正在寻找反馈,所以我有兴趣听听你的想法。

如果允许您编写类似于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)
        };
    });

它也是完全可扩展的!

文档仍在进行中,但您仍可以在线试用。

答案 2 :(得分:32)

更新:XQuery 3.1可以查询XML或JSON - 或同时查询两者。 XPath 3.1也可以。

名单正在增长:

答案 3 :(得分:9)

jmespath工作非常简单,http://jmespath.org/ 亚马逊在AWS命令行界面中使用它,因此它必须非常稳定。

答案 4 :(得分:8)

内置的array.filter() method使大多数这些所谓的javascript查询库过时了

您可以在代理中放置尽可能多的条件:简单比较,startsWith等。我还没有测试过,但您也可以嵌套过滤器来查询内部集合。

答案 5 :(得分:7)

对于复杂或未知结构的JSON文档,

ObjectPath是简单且易于使用的查询语言。它与XPath或JSONPath类似,但由于嵌入式算术计算,比较机制和内置函数,功能更强大。

Example

Python版本已经成熟并在生产中使用。 JS仍处于测试阶段。

可能在不久的将来,我们将提供完整的Javascript版本。我们还希望进一步开发它,以便它可以作为Mongo查询的简单替代方案。

答案 6 :(得分:6)

如果您使用.NET,那么Json.NET支持JSON顶部的LINQ查询。这个post有一些例子。它支持过滤,映射,分组等。

答案 7 :(得分:6)

另一种看待这种情况的方法是使用mongoDB您可以将您的JSON存储在mongo中,然后通过mongodb查询语法进行查询。

答案 8 :(得分:6)

jq是一种 J SON q uery语言,主要用于命令行,但绑定到各种编程语言(Java, node.js,php,...)甚至可以通过jq-web在浏览器中使用。

以下是一些基于原始问题的插图,以JSON为例:

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

SUM(X)WHERE Y> 0(等于7)

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

列表(X)在哪里> 0(等于[3,4])

map(.y > 0)

jq语法扩展了JSON语法

每个JSON表达式都是一个有效的jq表达式,而[1, (1+1)]和{" a":(1 + 1)}等表达式说明了jq如何扩展JSON语法。

一个更有用的例子是jq表达式:

{a,b}

,在给定JSON值{"a":1, "b":2, "c": 3}的情况下,评估为{"a":1, "b":2}

答案 9 :(得分:3)

这里有一些简单的javascript库也可以解决这个问题:

  • Dollar Q是一个不错的轻量级库。它对jQuery流行的链接语法有一种熟悉的感觉,只有373 SLOC。
  • SpahQL是一种功能齐全的查询语言,其语法类似于XPath(HomepageGithub
  • jFunk是一种正在进行的查询语言,其语法类似于CSS / jQuery选择器。它看起来很有希望,但在初始提交之后还没有任何发展。

  • (2014年新增):jq command line tool有一个简洁的语法,但不幸的是它是一个c库。用法示例:

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

答案 10 :(得分:3)

MongoDB中,这就是它的工作方式(在mongo shell中,存在您所选语言的驱动程序)。

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

前三个命令将数据插入到您的集合中。 (只需启动mongod服务器并与mongo客户端连接。)

接下来的两个处理数据。 $match过滤器,$group分别应用了sumlist

答案 11 :(得分:3)

好的,这篇文章有点陈旧,但是......如果你想在JS对象的原生JSON(或JS对象)中进行类似SQL的查询,请看看https://github.com/deitch/searchjs

它既是完全用JSON编写的jsql语言,也是参考实现。你可以说,“我想找到一个名为===”John“&amp;&amp; age = = 25的数组中的所有对象:

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

参考实现searchjs在浏览器中工作,也可以作为节点npm包

npm install searchjs

它也可以执行复杂连接和否定(NOT)之类的操作。它本身忽略了案例。

它还没有进行求和或计数,但在外面做这些可能更容易。

答案 12 :(得分:2)

  1. Google有一个名为 lovefield 的项目;刚刚发现它,它看起来很有趣,虽然它比仅仅用下划线或lodash更为复杂。

    https://github.com/google/lovefield

  2.   

    Lovefield是一个用纯JavaScript编写的关系查询引擎。它   还提供了在浏览器端持久保存数据的帮助,例如:   使用IndexedDB在本地存储数据。它提供类SQL语法和   适用于跨浏览器(目前支持Chrome 37 +,Firefox 31 +,IE   10+和Safari 5.1 + ......

    1. 这个空间最近有一个有趣的词条叫做 jinqJs

      http://www.jinqjs.com/

      简要回顾一下examples,看起来很有希望,API document似乎写得很好。

    2. 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是一个小巧,简单,轻量级和可扩展的javaScript   没有依赖关系的库。 jinqJs提供了一种简单的方法   在javaScript数组,集合和Web上执行类似SQL的查询   返回JSON响应的服务。 jinqJs类似于微软   .Net的Lambda表达式,它提供了类似的功能   使用类似SQL的语法和谓词功能查询集合。   jinqJs的目的是为程序员提供类似SQL的体验   熟悉LINQ查询。

答案 13 :(得分:2)


我刚刚完成了一个可发布版本的客户端JS-lib(defiant.js),可以满足您的需求。使用defiant.js,您可以使用您熟悉的XPath表达式查询JSON结构(没有像JSONPath中那样的新语法表达式)。

它的工作原理示例(请在浏览器中查看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

正如您所看到的,DefiantJS使用搜索功能扩展了全局对象JSON,并且返回的数组随聚合函数一起提供。 DefiantJS包含一些其他功能,但这些功能超出了本主题的范围。 Anywho,您可以使用客户端XPath评估程序测试lib。我认为不熟悉XPath的人会发现这个评估者很有用 http://defiantjs.com/#xpath_evaluator

有关defiant.js的更多信息 http://defiantjs.com/
https://github.com/hbi99/defiant.js

我希望你觉得它很有用...... 此致

答案 14 :(得分:2)

就我所知,SpahQL是最有前途和最深思熟虑的。我强烈建议您查看。

答案 15 :(得分:1)

你也可以使用Underscore.js,它基本上是一个瑞士刀库来操纵集合。使用_.filter_.pluck_.reduce,您可以执行类似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在客户端和服务器端都有效,是一个值得注意的库。

你也可以使用Lo-Dash,它是Underscore.js的一个表现更好的分支。

答案 16 :(得分:1)

只要有可能,我会将所有查询转移到服务器上的后端(到SQL DB或其他本机数据库类型)。原因是进行查询会更快,更优化。

我知道jSON可以单独使用,并且可能有+/-用于查询语言,但是如果您从后端检索数据到浏览器,我就看不到优势,就像大多数JSON用例一样。在后端查询和过滤,以获得所需的数据。

如果出于某种原因需要在前端查询(主要是在浏览器中),那么我建议只使用array.filter(为什么要发明其他内容?)。

那说我认为更有用的是json的转换API ...它们更有用,因为一旦你拥有数据,你可能希望以多种方式显示它。但是,如果您使用的是服务器&lt; - &gt;客户端模型,那么您可以在服务器上(可以更容易扩展)在客户端上执行大部分操作。

我的价值2便士!

答案 17 :(得分:1)

当前的Jaql实现针对使用Hadoop集群的大型数据处理,因此可能超出您的需要。但是,它在没有Hadoop集群的情况下很容易运行(但仍然需要编译Hadoop代码及其依赖项,这些代码主要包括在内)。可以嵌入Javascript和浏览器的Jaql的一个小实现将是项目的一个很好的补充。

上面的示例很容易用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]

当然,还有更多。例如:

// 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 }}]

可以在http://code.google.com/p/jaql/

下载/讨论Jaql

答案 18 :(得分:1)

我将仅仅使用您自己的javascript的概念,但对于更复杂的东西,您可能会看dojo data。没有使用它,但看起来它给你大致提供了你正在寻找的那种查询界面。

答案 19 :(得分:1)

PythonQL提供了一种嵌入式语法,即IMHO是SQL的改进,主要是因为2 HOURS<div fxLayout="row" fxLayoutAlign="start"> <div class="text1">hey, how are</div> <div class="text2"> you?</div> </div> groupwindow等可以自由地混合。 / p>

where

此代码根据您处理整个结构或只是值的需要,显示了针对您问题的两个不同答案。执行将为您带来预期的结果。

let

答案 20 :(得分:0)

查看https://github.com/niclasko/Cypher.js(注意:我是作者)

它是Cypher图形数据库查询语言以及图形数据库的零依赖Javascript实现。它在浏览器中运行(已通过Firefox,Chrome,IE测试)。

与该问题有关。可用于查询JSON端点:

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

下面是查询复杂的JSON文档并对其进行分析的示例:

Cypher.js JSON query example

答案 21 :(得分:0)

您可以使用linq.js

这允许将聚合和从对象的数据集中选择作为其他结构数据。

<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
!= ''

答案 22 :(得分:0)

如果您想使用纯JavaScript,请尝试以下操作:

var object = { result: { data: { point1: "x", value: 2 }, foo: { bar: 7 } } },
    path = 'result.data.value',
    getValue = (o, p) => p.split('.').reduce((r, k) => r[k], o);

console.log(getValue(object, path));