是否有JSON的查询语言?

问题描述 投票:201回答:20

是否有(大致)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)

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

有什么建议?

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

json nosql web-standards querying dynamic-queries
20个回答
80
投票

当然,怎么样:

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

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


3
投票

好的,这篇文章有点旧,但是......如果你想在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)之类的事情。它本身忽略了大小写。

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


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'

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


2
投票

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


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

我希望你觉得它很有用......问候


2
投票
  1. 谷歌有一个名为lovefield的项目;刚刚发现它,它看起来很有趣,虽然它更多涉及而不仅仅是下划线或lodash。 https://github.com/google/lovefield

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


  1. 这个空间中另一个有趣的新进入名为jinqJs。 http://www.jinqjs.com/ 简要回顾一下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提供了一种简单的方法来执行SQL,例如对返回JSON响应的javaScript数组,集合和Web服务的查询。 jinqJs类似于Microsoft的.Net的Lambda表达式,它提供了类似的功能,可以使用SQL语法和谓词功能来查询集合。 jinqJs的目的是为熟悉LINQ查询的程序员提供类似SQL的体验。


1
投票

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


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可以在http://code.google.com/p/jaql/下载/讨论


1
投票

你也可以使用qazxsw poi,它基本上是一个瑞士刀库来操纵集合。使用qazxsw poi,qazxsw poi,Underscore.js你可以做类似SQL的查询。

_.filter

Underscore.js可以在客户端和服务器端工作,是一个值得注意的库。

你也可以使用_.pluck,这是一个具有更好性能的Underscore.js的分支。


1
投票

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

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

如果由于某种原因你需要在前端查询(主要是在浏览器中),那么我建议只使用array.filter(为什么要发明别的东西?)。

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

只值2便士!


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

它也是完全可扩展的!

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


0
投票

查看_.reduce(注意:我是作者)

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

与问题相关。它可用于查询JSON端点:

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

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

Lo-Dash


32
投票

更新:XQuery 3.1可以查询XML或JSON - 或两者一起查询。而XPath 3.1也可以。

名单正在增长:


9
投票

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


8
投票

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

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


7
投票

ObjectPath是复杂或未知结构的JSON文档的简单和ligthweigth查询语言。它与XPath或JSONPath类似,但由于嵌入式算术计算,比较机制和内置函数,功能更强大。

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

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


6
投票

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


6
投票

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


6
投票

jq是一种JSON查询语言,主要用于命令行,但绑定到各种编程语言(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)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}

© www.soinside.com 2019 - 2024. All rights reserved.