有没有JSON的查询语言?
是否有一个(粗略)SQL或XQuery类似的查询JSON语言?
我正在考虑非常小的数据集,这些数据集可以很好地映射到JSON,在这种情况下很容易回答诸如“Y> 3的所有X的值是什么”或执行常规的SUM / COUNTtypes操作。
作为完整的例子,像这样的东西:
[{"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)
一个快速的谷歌search表明,人们已经想到了它,并实现了一些东西( JAQL ),但似乎并没有一个标准的用法或一套库已经出现了。 虽然每个function本身都是相当简单的,但如果有人已经做对了,我不想重新发明轮子。
有什么build议么?
编辑:这可能确实是一个坏主意或JSON可能是太通用的格式,我在想什么。想要一个查询语言,而不是直接根据需要做求和/ etcfunction的原因是,我希望build立查询dynamic基于用户input。 有点像“我们不需要SQL,我们可以写我们需要的function”的论点。 最终,要么失控,要么随着你越来越深入地写出你自己的SQL版本。 (好吧,我知道这是一个愚蠢的论点,但你明白了..)
当然,如何:
- JAQL
- JsonPath 。
- Json查询
他们似乎都在努力工作,但在某种程度上工作。 它们在概念上也类似于XPath和XQuery; 即使XML和JSON有不同的概念模型(层次结构vs对象/结构)。
编辑 2015年9月:其实现在有JSON指针标准,允许非常简单和有效的JSON内容遍历。 它不仅被正式指定,而且还被许多JSON库所支持。 所以我会把它称为实际的有用的标准,尽pipe由于其有限的expression能力,它可能会或可能不会被视为查询语言本身。
我build议我正在做的项目叫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) }; });
它也是完全可扩展的!
文档仍在进行中,但您仍可以在线尝试。
更新: XQuery 3.1可以查询XML或JSON – 或两者一起。 而且XPath 3.1也可以。
名单正在增长:
- JSONiq (基于XQuery)
- UNQL (如SQL)
- JaQL (function)
- JsonPath (类XPath)
- Json查询 (类似于XPath)
- GraphQL (基于模板,键入)
内置的array.filter()
方法使得大多数这些所谓的javascript查询库过时
你可以在代理内部放置尽可能多的条件:简单的比较,startsWith等。我还没有testing,但是你也可以嵌套filter来查询内部集合。
jmespath的工作真的很简单, http: //jmespath.org/它在Amazon命令行界面中被Amazon使用,所以它非常稳定。
如果你使用.NET,那么Json.NET支持JSON顶部的LINQ查询。 这篇文章有一些例子。 它支持过滤,映射,分组等。
另一种方法来看待这将是使用mongoDB您可以将您的JSON存储在mongo中,然后通过mongodb查询语法来查询它。
对于复杂或未知结构的JSON文档,ObjectPath非常简单,只需查询语言即可。 它与XPath或JSONPath类似,但由于embedded式算术计算,比较机制和内置函数,function更加强大。
Python版本是成熟的,并在生产中使用。 JS仍处于testing阶段。
可能在不久的将来,我们将提供一个完整的Javascript版本。 我们还想进一步开发它,以便它可以作为Mongo查询的一个简单的替代scheme。
好的,这个post有点旧了,但是如果你想在JS对象的原生JSON(或JS对象)中做类似于SQL的查询,请看https://github.com/deitch/searchjs
它既是一个完全用JSON编写的jsql语言,也是一个参考实现。 你可以这样说:“我想查找名字===”John“&& age === 25的数组中的所有对象,如下所示:
{name:"John",age:25,_join:"AND"}
参考实现searchjs可以在浏览器中使用,也可以作为节点npm包使用
npm install searchjs
它也可以做复杂的连接和否定(NOT)。 它本身忽略了案件。
它还没有进行总结或计数,但在外面做这些可能更容易。
这里有一些简单的JavaScript库,也将做的伎俩:
- 美元Q是一个不错的轻量级图书馆。 它对jQuery所使用的链式语法有一个熟悉的感觉,只有373个SLOC。
- SpahQL是一个全function的查询语言,语法类似于XPath( Homepage , Github
-
jFunk是一种进行中的查询语言,语法类似于CSS / jQueryselect器。 它看起来很有希望,但在最初的承诺之后没有任何发展。
-
(增加2014年): jq命令行工具有一个整洁的语法,但不幸的是它是ac库。 用法示例:
< package.json jq '.dependencies | to_entries | .[] | select(.value | startswith("git")) | .key'
据我所知,SpahQL是最有前途和最深思的。 我强烈build议检查一下。
我刚刚完成了一个客户端JS-lib(defiant.js)的可发布版本,它可以完成你正在寻找的任务。 使用defiant.js,您可以使用您熟悉的XPathexpression式来查询JSON结构(没有JSONPath中的新语法expression式)。
它的工作原理示例(在浏览器中查看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使用searchfunction扩展全局对象JSON,并返回具有聚合函数的数组。 DefiantJS包含一些其他的function,但这些都超出了这个问题的范围。 任何人,你可以用一个客户端的XPath评估器来testing这个库。 我认为不熟悉XPath的人会发现这个评估器有用。
http://defiantjs.com/#xpath_evaluator
有关defiant.js的更多信息
http://defiantjs.com/
hbi99/defiant.html
我希望你觉得它有用…关心
在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
filter, $group
应用sum
和list
。
我将第二个使用自己的JavaScript的概念,但对于更复杂的东西,你可能会看dojo数据 。 没有使用它,但它看起来像它给你粗略的查询界面,你正在寻找。
目前的Jaql实现针对使用Hadoop集群的大数据处理,因此可能比您需要的要多。 但是,如果没有Hadoop集群,它很容易运行(但是仍然需要Hadoop代码及其依赖关系才能进行编译,而这些主要包括在内)。 Jaql的一个小实现可以embedded到Javascript和一个浏览器中,这对项目来说是一个很好的补充。
上面的例子很容易用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 }}]
-
Google有一个名为“ lovefield”的项目; 只是发现了它,它看起来很有趣,虽然它比在下划线或lodash放下更多的参与。
Lovefield是一个用纯JavaScript编写的关系查询引擎。 它还提供了在浏览器端保存数据的帮助,例如使用IndexedDB在本地存储数据。 它提供了类似于SQL的语法 ,可以跨浏览器(目前支持Chrome 37 +,Firefox 31 +,IE 10+和Safari 5.1 +)。
-
在这个空间另一个有趣的最近的项目称为jinqJs 。
简要回顾一下这些例子 ,看起来很有希望, API文档似乎写得很好。
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提供了一个简单的方法来执行SQL查询返回JSON响应的javaScript数组,集合和Web服务。 jinqJs类似于微软的.Net的Lambdaexpression式,它提供了类似的function来查询使用SQL语法和谓词function的集合。 jinqJs的目的是为熟悉LINQ查询的程序员提供一种类似于SQL的体验。
你也可以使用基本上是瑞士刀库的Underscore.js来操作集合。 使用_.filter
, _.pluck
. _.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的一个分支,具有更好的性能。
只要有可能,我会将所有的查询转移到服务器上的后端(到SQL DB或其他本地数据库types)。 原因在于它会更快,更优化地进行查询。
我知道json可以独立运行,可能会有+ / – 有一个查询语言,但我不能看到的优势,如果你从后端检索到浏览器的数据,因为大部分的JSON用例。 在后端查询和过滤以获得所需的数据。
如果因为某种原因你需要在前端查询(主要是在浏览器中),那么我会build议使用array.filter(为什么要发明别的东西?)。
这就是说我认为更有用的是一个转换API的JSON …他们更有用,因为一旦你有数据,你可能需要以多种方式显示它。 不过,如果你使用的是服务器客户端模式,你可以在服务器上做很多事情(比较容易扩展)。
只是我的2便士值得!