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のバージョンを書くことになります。 (さて、私はそれが少しばかげた議論であることを知っていますが、あなたはアイデアを得る..)
もちろん、どうですか:
それらはすべて少し進行中の作業のようですが、ある程度は機能します。また、概念的にはXPathとXQueryに似ています。 XMLとJSONには異なる概念モデル(階層型vsオブジェクト/構造)がありますが。
EDIT2015年9月:実際には、JSONコンテンツの非常にシンプルで効率的なトラバースを可能にする JSON Pointer 標準があります。正式に指定されているだけでなく、多くの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/ これはAmazonによってAWSコマンドラインインターフェイスで使用されているため、非常に安定している必要があります。
組み込みの array.filter()
method は、これらのいわゆるJavaScriptクエリライブラリのほとんどを廃止します
単純な比較、startsWithなど、想像できる限り多くの条件をデリゲート内に置くことができます。テストしていませんが、内部コレクションのクエリ用にフィルターをネストすることもできます。
ObjectPath は、複雑な構造または不明な構造のJSONドキュメント用のシンプルで軽量なクエリ言語です。 XPathやJSONPathに似ていますが、算術計算、比較メカニズム、組み込み関数が組み込まれているため、はるかに強力です。
Pythonバージョンは成熟しており、実稼働で使用されます。 JSはまだベータ版です。
おそらく近い将来、本格的なJavascriptバージョンを提供する予定です。また、Mongoクエリのより単純な代替として機能できるように、さらに開発したいと考えています。
jq はaJSONq主にコマンドライン向けですが、広範囲のプログラミング言語(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)
すべての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をmongoに保存し、mongodbクエリ構文を使用してクエリすることができます。
トリックを行う簡単なJavaScriptライブラリを次に示します。
jFunk は、CSS/jQueryセレクターに似た構文を持つ進行中のクエリ言語です。有望に見えましたが、最初のコミットでの開発を超えた開発はありません。
(2014年追加): jqコマンドラインツール にはきちんとした構文がありますが、残念ながらcライブラリです。使用例:
< package.json jq '.dependencies | to_entries | .[] | select(.value | startswith("git")) | .key'
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)のようなこともできます。大文字小文字をネイティブで無視します。
まだ集計やカウントは行いませんが、おそらく外部で行う方が簡単です。
MongoDB では、これがどのように機能するかです(mongoシェルでは、選択した言語のドライバーが存在します)。
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
クライアントに接続するだけです。)
SpahQLは、私が知る限り、これらの中で最も有望でよく考えられています。チェックアウトすることを強くお勧めします。
Googleにはlovefieldというプロジェクトがあります。ただそれを見つけただけで、おもしろそうに見えますが、アンダースコアやダッシュを入れるよりも複雑です。
Lovefieldは、純粋なJavaScriptで記述されたリレーショナルクエリエンジンです。また、ブラウザ側でのデータの永続化に関するヘルプも提供します。 IndexedDBを使用してデータをローカルに保存します。 SQLライクな構文を提供し、クロスブラウザで動作します(現在Chrome 37 +、Firefox 31 +、IE 10+、およびSafari 5.1 + ...
jinqJsと呼ばれるこのスペースの別の興味深い最近のエントリ。
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を実行する簡単な方法を提供します。 jinqJsは、MicrosoftのLambda式の.Netに似ており、構文や述語機能のようなSQLを使用してクエリコレクションに同様の機能を提供します。 jinqJsの目的は、LINQクエリに精通したプログラマーにSQLのような経験を提供することです。
探していることを実行するクライアントサイド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
役立つと思います...よろしく
nderscore.js を使用することもできます。これは基本的に、コレクションを操作するためのswiss-knifeライブラリです。 _.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のフォークです。
可能な限り、すべてのクエリをサーバー上のバックエンド(SQL DBまたは他のネイティブデータベースタイプ)にシフトします。理由は、クエリを実行するためにより速く最適化されるからです。
私はjSONがスタンドアロンであり、クエリ言語を持っているために+ /-があるかもしれないことを知っていますが、ほとんどのJSONユースケースのように、バックエンドからブラウザにデータを取得している場合、私は利点を見ることができません。バックエンドでクエリとフィルタリングを行い、必要なデータをできるだけ小さくします。
何らかの理由でフロントエンド(主にブラウザで)でクエリを実行する必要がある場合は、array.filterを使用することをお勧めします(なぜ他の何かを発明するのですか?)。
それは、私がより有用だと思うのは、jsonの変換APIです...データを取得したら、それをさまざまな方法で表示したい場合があるためです。ただし、この場合も、サーバーよりも多くのことを行うことができます(スケーリングがはるかに簡単になる可能性があります)。これは、サーバー<->クライアントモデルを使用している場合です。
ちょうど私の2ペンスの価値!
私はあなた自身のjavascriptを使用するという概念を2番目に取り上げますが、もう少し洗練されたものについては dojo data を参照してください。使用していませんが、おおよその種類のクエリインターフェイスを探しているようです。
チェックアウト 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
を使用できます。
これにより、他の構造データとして、オブジェクトのデータセットからの集計と選択を使用できます。
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>