是否有用于查询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版本。 (好吧,我知道这是一个有点愚蠢的论点,但你明白了。)
答案 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)
ObjectPath是简单且易于使用的查询语言。它与XPath或JSONPath类似,但由于嵌入式算术计算,比较机制和内置函数,功能更强大。
Python版本已经成熟并在生产中使用。 JS仍处于测试阶段。
可能在不久的将来,我们将提供完整的Javascript版本。我们还希望进一步开发它,以便它可以作为Mongo查询的简单替代方案。
答案 6 :(得分:6)
答案 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)
每个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库也可以解决这个问题:
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
客户端连接。)
答案 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)
Google有一个名为 lovefield 的项目;刚刚发现它,它看起来很有趣,虽然它比仅仅用下划线或lodash更为复杂。
Lovefield是一个用纯JavaScript编写的关系查询引擎。它 还提供了在浏览器端持久保存数据的帮助,例如: 使用IndexedDB在本地存储数据。它提供类SQL语法和 适用于跨浏览器(目前支持Chrome 37 +,Firefox 31 +,IE 10+和Safari 5.1 + ......
这个空间最近有一个有趣的词条叫做 jinqJs 。
简要回顾一下examples,看起来很有希望,API document似乎写得很好。
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 }}]
下载/讨论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>
,group
,window
等可以自由地混合。 / 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文档并对其进行分析的示例:
答案 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));