是否有(大致)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 版本,因为你将它推得越来越远。(好吧,我知道这有点愚蠢,但你明白了..)

有帮助吗?

解决方案

当然可以,怎么样:

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

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

其他提示

我会建议我的项目,我的工作称为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 也可以。

该名单正在不断增加:

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}.

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

来看待这个另一种方法是使用 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 客户。)

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

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

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

  1. 谷歌有一个项目叫 洛夫菲尔德;刚刚发现它,它看起来很有趣,尽管它比仅仅添加下划线或 lodash 更复杂。

    https://github.com/google/lovefield

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


  1. 该领域最近另一个有趣的条目称为 金青山.

    http://www.jinqjs.com/

    简要回顾一下 例子, ,它看起来很有前途,并且 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提供了一种简单的方法,可以在返回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 文档并对其进行分析的示例:

Cypher.js 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>

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top