JSONのクエリ言語はありますか?


227

JSONをクエリするための(大まかに)SQLまたはXQueryのような言語はありますか?

「Xのすべての値がY> 3である」などのクエリに簡単に応答したり、通常のSUM / COUNTタイプの操作を実行したりすると、JSONに適切にマッピングされる非常に小さなデータセットを考えています。

完全に構成された例として、次のようなもの:

[{"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リクエストを、オブジェクトツリーの特定の場所にある特定の値と照合する必要があります。クエリは、実際には(パワー)ユーザーが構成する必要があります。現在の回避策は、JSONからその場しのぎのXMLを構築し、XPathを適用することです。
ウラジミールデュジェフ

1
これはシェルツールのようなものですが、jq(stedolan.github.io/jq)はjsonデータの探索に最適です。遊び場で試してみてください:jqplay.org
jtmoulia

sqall.coのパブリックJSONフィードまたはAPIでSQLクエリを実行できるWebベースのツールがあります。
Stack Man


回答:


91

はい、どうですか:

それらはすべて少し進行中のようですが、ある程度は動作します。また、概念的にはXPathおよびXQueryに似ています。XMLとJSONの概念モデルは異なりますが(階層vsオブジェクト/構造)。

2015年9月の編集:実際には、JSONコンテンツの非常にシンプルで効率的なトラバーサルを可能にするJSONポインター標準があります。正式に指定されているだけでなく、多くのJSONライブラリでもサポートされています。したがって、私はそれを実際の有用な標準と呼びますが、その表現力の制限により、それ自体がクエリ言語と見なされる場合と見なされない場合があります。


77
言い換えれば、標準的で安定したものは何もない... :-(
Vladimir Dyuzhev

標準について話すと、XQuery 3.1がJSONクエリをサポートするように拡張される可能性があるという噂を聞きました(JSONiqと同様)。もちろん、XQuery 3.0がまだ正式にリリースされていないため、しばらく時間がかかる場合があります。
Julien Ribon

ああ慈悲、私は間違いなく願っています。私が見たすべてのXML-> JSONの試みは恐ろしい混乱でした-情報モデルは互換性がありません。しかし、私はJQueryが同じアイデア、構文の一部を使用することを望んでいます。JSON情報モデルに正しく変更されました。
StaxMan

1
JSONPathのRuby実装をお探しの方:github.com/joshbuddy/jsonpath
Robert Ross

@GôTô:その自由があれば、MongoDBを使用することは実行可能なアプローチのようです。(クエリを組み込みシェルに変換する方法の例については、以下回答を参照してください)
serv-inc

48

私が取り組んでいる私のプロジェクトは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)
        };
    });

それも完全に拡張可能です!

ドキュメントはまだ作成中ですが、オンラインで試すことができます。


@hugoware:これに関するドキュメントはありますか?.starts()以外のクエリ(containsなど)はありますか
Rikki

5
最後の更新は8年前で、プロジェクトが5年前に死んでいるかどうかを尋ねられても返答はありません...プロジェクトは死んでいると思います。
cfc 2018年


14

jmespathは実際にはかなり簡単で、うまく機能し、http://jmespath.org/ it'sはかなり安定するようになったので、それは、AWSコマンドラインインターフェイスにAmazonが使用されています。


5
しかし、同じページで同時に:「--queryでは実現できない可能性があるより高度な機能が必要な場合は、コマンドラインJSONプロセッサであるjqをチェックアウトできます。」したがって、AWSはパラメーターに使用jmespathしているようです--queryjq、コマンドラインパイピングをお勧めします。docs.aws.amazon.com/cli/latest/userguide/...
wisbucky

10

jqJ 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

LIST(X)WHERE Y> 0([3,4]と同等)

map(.y > 0)

jq構文はJSON構文を拡張します

すべてのJSON式は有効なjq式であり、[1, (1+1)]and {"a":(1 + 1)} ` などの式は、jqがJSON構文を拡張する方法を示しています。

より有用な例は、jq式です。

{a,b}

これは、JSON値を指定すると{"a":1, "b":2, "c": 3}、に評価され{"a":1, "b":2}ます。


8

組み込みarray.filter()メソッドにより、これらのいわゆるJavaScriptクエリライブラリのほとんどが廃止されます

デリゲート内には、想像できる限り多くの条件を設定できます。単純な比較、startsWithなどです。私はテストしていませんが、内部コレクションをクエリするためにフィルターをネストすることもできます。


5
array.filter()JSONではなくJavaScriptの一部です。
Iain Samuel McLean Elder 14年

2
JSONはJavaScriptのサブセットですが、JSONと配列の両方をサポートし、配列フィルターメソッドが実装されている言語はたくさんあるので、これは有効な点です。
ダカブ2015年


7

ObjectPathは、複雑な構造または未知の構造のJSONドキュメント用のシンプルで高度なクエリ言語です。これはXPathまたはJSONPathに似ていますが、組み込み算術計算、比較メカニズム、および組み込み関数により、はるかに強力です。

例

Pythonバージョンは成熟しており、本番環境で使用されています。JSはまだベータ版です。

おそらく近い将来、本格的なJavascriptバージョンを提供する予定です。また、Mongoクエリのより簡単な代替手段として機能するように、さらに開発したいと考えています。


1
ドキュメントがほとんどないことを除いて、何かのようなテキストを持つ要素を見つけるなど、何かを行う方法を見つけるのは難しいです。
James O'Brien

1
@ JamesO'Brien発言ありがとうございます。参照が役に立たず、特定の問題が発生する場合は、こちらからお知らせください-誰かがお手伝いします。現在、ドキュメントをより使いやすくするために取り組んでいます。コメントをお待ちしています。
Ela Bednarek 2014年

ありがとう-ありがとう。利用したいです。現在、ashphy.com / JSONPathOnlineEvaluatorを使用してますか?
James O'Brien

ドキュメントがまったくないため、JavaScriptでこれを使用する方法を理解できませんでした。
user3670743

私たちはそれを手伝ってくれる貢献者を探しています。達成しようとしていることをGithubまたはgoogle groups groups.google.com/forum/#!members/objectpathに書き込むことができます。誰かがあなたのQに答えると確信しています。
Ela


4

OK、この投稿は少し古いですが... JSオブジェクトでネイティブJSON(またはJSオブジェクト)でSQLのようなクエリを実行する場合は、https://github.com/deitch/searchjsをご覧ください。

完全にJSONで記述されたjsql言語であり、リファレンス実装でもあります。たとえば、「name === "John" && age === 25である配列内のすべてのオブジェクトを検索したい場合:

{name:"John",age:25,_join:"AND"}

リファレンス実装searchjsは、ブラウザーとノードnpmパッケージで動作します

npm install searchjs

また、複雑な結合や否定(NOT)なども実行できます。大文字小文字を無視します。

まだ集計もカウントもしていませんが、外部で行う方がおそらく簡単です。


3

これもトリックを実行するいくつかの単純なJavaScriptライブラリです。

  • ドルQは素晴らしい軽量ライブラリです。jQueryによって普及したチェーン構文に馴染みがあり、SLOCはわずか373です。
  • SpahQLは、XPath(HomepageGithub
  • jFunkは、CSS / jQueryセレクターに似た構文を持つ進行中のクエリ言語です。それは有望に見えたが、最初のコミットでそれを超える発展はなかった。

  • (2014年追加):jqコマンドラインツールの構文は簡潔ですが、残念ながらACライブラリです。使用例:

    < package.json jq '.dependencies | to_entries | .[] | select(.value | startswith("git")) | .key'


3

MongoDBは、これは(モンゴシェルでは、選択した言語用のドライバが存在する)どのように動作するかです。

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

最初の3つのコマンドは、データをコレクションに挿入します。(mongodサーバーを起動してmongoクライアントに接続するだけです。)

次の2つはデータを処理します。$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には他のいくつかの機能が含まれていますが、それらはこの主題の範囲外です。誰でも、クライアントサイドのXPathエバリュエーターでライブラリをテストできます。XPathに慣れていない人は、このエバリュエーターが役立つと思います。
http://defiantjs.com/#xpath_evaluator

defiant.jsの詳細
http://defiantjs.com/
https://github.com/hbi99/defiant.js

お役に立てば幸いです...


現在、結果への完全なパスを取得することは可能ですか?
XeniaSis 2017

2
  1. Googleにはlovefieldというプロジェクトがあります。ちょうどそれについて知った、そしてそれは面白いように見えるが、それは単に下線やロダッシュを入れるよりも複雑である。

    https://github.com/google/lovefield

Lovefieldは、純粋なJavaScriptで記述されたリレーショナルクエリエンジンです。また、ブラウザ側でのデータの永続化、たとえばIndexedDBを使用してデータをローカルに保存するためのヘルプも提供します。SQLに似た構文を提供し、クロスブラウザーで動作します(現在、Chrome 37以降、Firefox 31以降、IE 10以降、およびSafari 5.1以降をサポートしています...


  1. このスペースの別の興味深い最近のエントリはjinqJsです。

    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は、JavaScript配列、コレクション、JSON応答を返すWebサービスでSQLのようなクエリを実行する簡単な方法を提供します。jinqJsは、Microsoftの.NetのLambda式に似ており、SQLに似た構文と述語機能を使用してコレクションをクエリするのと同様の機能を提供します。jinqJsの目的は、LINQクエリに精通したプログラマーにSQLのような体験を提供することです。


1

次に、独自のJavaScriptを使用するという概念を説明しますが、もう少し洗練されたものについては、道場データを見てみましょう。まだ使用していませんが、お探しのクエリインターフェイスの種類をおおまかに提供しているようです。


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

また、基本的にスイスナイフライブラリであるUnderscore.jsを使用して、コレクションを操作することもできます。、を使用する_.filter_.pluck_.reduceSQLに似たクエリを実行できます。

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のフォークであるLo-Dashを使用することもできます。


1

可能な限り、すべてのクエリをサーバーのバックエンド(SQL DBまたは他のネイティブデータベースタイプ)にシフトします。理由は、クエリを実行する方がより速く、より最適化されることです。

jSONはスタンドアロンであり、クエリ言語を使用することで+/-が存在する可能性があることはわかっていますが、JSONのほとんどのユースケースであるように、バックエンドからブラウザーにデータを取得する場合、利点はわかりません。バックエンドでクエリとフィルタリングを行い、必要なデータをできるだけ小さくします。

なんらかの理由でフロントエンド(主にブラウザー)でクエリを実行する必要がある場合は、array.filterを使用することをお勧めします(なぜ他のものを発明するのですか?)。

そうは言っても、jsonの変換APIの方が便利だと思います。データが得られたら、さまざまな方法で表示したいので、jsonの変換APIの方が便利です。ただし、この場合も、サーバーよりも(スケーリングがはるかに簡単です)サーバーで実行できます(サーバー<->クライアントモデルを使用している場合)。

2ペンス相当!


1

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クエリの例


1

PythonQLは、主にので、私見は、SQLの改善であることを埋め込まれた構文を提供しています groupwindowwherelet、など自由に混在させることができます。

$ cat x.py
#coding: pythonql
data = [{"x": 2, "y": 0}, {"x": 3, "y": 1}, {"x": 4, "y": 1}]
q = [x match {'x': as x, 'y': as y} in data where y > 0]
print(sum(q))
print(list(q))

q = [x match {'x': as x, 'y': as y} as d in data where d['y'] > 0]
print(sum(q))

このコードは、構造全体または値のみを処理する必要性に応じて、質問に対する2つの異なる回答を示します。実行すると、期待どおりの結果が得られます。

$ python x.py
7
[3, 4]
7

0

あなたは使うことができます linq.js

これにより、他の構造データとして、オブジェクトのデータセットからの集計と選択を使用できます。

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>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.