有 JSON 的查询语言吗?
-
13-09-2019 - |
题
是否有(大致)SQL 或类似 XQuery 的语言用于查询 JSON?
我正在考虑可以很好地映射到 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)
快速谷歌搜索表明人们已经考虑过它并实施了一些事情(贾克利),但似乎还没有出现标准用法或库集。虽然每个功能单独实现都相当简单,但如果有人已经正确完成了,我不想重新发明轮子。
有什么建议么?
编辑:这可能确实是一个坏主意,或者 JSON 对于我的想法来说可能太通用了。想要一种查询语言而不是只根据需要直接执行求和/等功能的原因是我希望根据用户输入动态构建查询。有点像“我们不需要 SQL,我们可以只编写我们需要的函数”的论点。最终,要么会失控,要么你最终会编写自己的 SQL 版本,因为你将它推得越来越远。(好吧,我知道这有点愚蠢,但你明白了..)
其他提示
我会建议我的项目,我的工作称为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)
};
});
这是完全可扩展的呢!
在文档仍在进行中,但你仍然可以在线试用。
jmespath作品真的很容易和好, http://jmespath.org/ 它被用来由亚马逊在AWS命令行界面,所以it's得相当稳定。
内置 array.filter()
方法使得大多数的这些所谓的JavaScript库查询过时
您可以把尽可能多的条件委托,你可以想像里面:简单的比较,startsWith等我还没有测试,但你也许可以嵌套过滤过的查询里面的收藏
。ObjectPath 是对于复杂的或未知结构的JSON文档简单和ligthweigth查询语言。它类似于XPath或JSONPath,但更强大得益于嵌入式算术运算,比较机制和内置功能。
Python版本是成熟和在生产中使用。 JS仍处于测试阶段。
也许在不久的将来,我们将提供一个全面的Javascript版本。我们也希望进一步发展它,这样它可以作为到蒙戈查询一个简单的选择。
杰克 是一个 J儿子 query 语言,主要用于命令行,但与多种编程语言(Java、node.js、php...)绑定,甚至可以通过浏览器使用 杰青网.
以下是基于原始问题的一些说明,以 JSON 为例:
[{"x": 2, "y": 0}}, {"x": 3, "y": 1}, {"x": 4, "y": 1}]
SUM(X) 其中 Y > 0(等于 7)
map(select(.y > 0)) | add
LIST(X) WHERE Y > 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}
.
来看待这个另一种方法是使用 MongoDB的你可以将JSON存储在蒙戈,然后通过mongodb的查询语法查询。
OK,这个职位是有点老了,但是......如果你想要做在JS对象本地JSON(或JS对象)类似SQL的查询,看看的 https://github.com/deitch/searchjs
有两个完全在JSON写入一个JSQL语言,和一个参考实现。你可以说,“我想找到有名称的数组所有的对象===”约翰” &&年龄=== 25为:
{name:"John",age:25,_join:"AND"}
参考实现searchjs在浏览器中以及作为节点NPM包作品
npm install searchjs
它也可以做这样的事情复杂的连接和否定(NOT)。它本身忽略大小写。
这还不做求和或计数,但它可能是更容易做到的外面。
这里有一些简单的 javascript 库也可以实现这个目的:
- 美元Q 是一个不错的轻量级库。它对 jQuery 流行的链接语法有一种熟悉的感觉,并且只有 373 个 SLOC。
- 斯帕赫QL 是一种功能齐全的查询语言,其语法类似于 XPath (主页, 吉图布
芬克 是一种正在进行的查询语言,其语法类似于 CSS/jQuery 选择器。它看起来很有希望,但除了最初的承诺之外还没有任何进展。
(2014 年添加):这 jq 命令行工具 有一个简洁的语法,但不幸的是它是一个 C 库。用法示例:
< package.json jq '.dependencies | to_entries | .[] | select(.value | startswith("git")) | .key'
在 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
客户。)
SpahQL是最有前途的和深思熟虑的这些,据我可以告诉。我强烈建议检查出来。
,点击 我刚刚完成,做你正在寻找一个客户方JS-LIB(defiant.js)的可释放的版本。随着defiant.js,您可以查询JSON结构与你熟悉(没有新的语法表达在JSONPath)的XPath表达式。
它是如何工作实施例(见它在浏览器这里 HTTP:// defiantjs的.com / defiant.js /演示/ 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
我希望你觉得它有用... 此致
谷歌有一个项目叫 洛夫菲尔德;刚刚发现它,它看起来很有趣,尽管它比仅仅添加下划线或 lodash 更复杂。
Lovefield 是一个用纯 JavaScript 编写的关系查询引擎。它还为浏览器端的持续数据提供帮助,例如使用 IndexedDB 在本地存储数据。它提供 类似 SQL 的语法 和Works Cross-Browser(目前支持Chrome 37+,Firefox 31+,IE 10+和Safari 5.1+...
该领域最近另一个有趣的条目称为 金青山.
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提供了一种简单的方法,可以在返回JSON响应的JavaScript数组,集合和Web服务上执行SQL之类的SQL。JINQJS类似于Microsoft的.NET lambda表达式,它提供了类似的功能,可以使用SQL诸如语法和谓词功能等SQL查询收集。JINQJS的目的是向熟悉LINQ查询的程序员提供类似的经验。
我将第二只使用自己的JavaScript的概念,但对于一些更复杂的你可能看的道场数据。还没有使用它,但它看起来像它可以让你大致那种你正在寻找的查询界面。
使用Hadoop集群,所以它可能是比你更需要的电流JAQL实现目标的大数据处理。但是,它很容易运行没有Hadoop集群(但仍需要Hadoop的代码和它依赖于被编译,基本都是包括在内)。一个小的实现JAQL的,可以被嵌入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 }}]
JAQL可以下载/讨论在 http://code.google.com/p/jaql /
您还可以使用 下划线.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 可在客户端和服务器端运行,是一个著名的库。
您还可以使用 洛达什 这是 Underscore.js 的一个分支,具有更好的性能。
只要有可能我将所有所述查询的转移到后端服务器上(到SQL DB或其他本地数据库类型)。原因是是,这将是更快,更优化办查询。
我知道,JSON可以独立并有可能成为+/-对于具有查询语言,但我看不到的优势,如果你是从后端到浏览器检索数据,因为大多数的JSON用例。查询和过滤器在后端得到尽可能小,以致需要一个数据。
如果出于某种原因,你需要在前端(主要是在浏览器中)查询,那么我会用array.filter建议刚(为什么别人发明的东西?)。
这是说什么,我想会更有用是一个转型的API JSON ......他们更加有用,因为一旦你有,你可能希望通过多种方式来显示它的数据。然而,同样,你可以做很多的这个服务器(可缩放容易得多)比客户端上 - 如果你正在使用服务器< - >客户端模型
只是我的2个便士!
查看 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 文档并对其进行分析的示例:
您可以使用 linq.js
。
这允许使用的聚合和selectings从对象的数据集,因为其他结构的数据。
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>