web-dev-qa-db-ja.com

SQLiteにJSONを格納してクエリを実行することはできますか?

JSONオブジェクトをSQLiteデータベースに保存し、それに対して複雑なクエリを実行する必要があります。

私はこのようなテーブルを作りました:

+--------------------------------------+
|document |  property | string | number|
+--------------------------------------+
|foo      |  "title"  | "test" |       | 
+--------------------------------------+
|foo      |  "id"     |        |  42   | 
+--------------------------------------+
|bar      |  "id"     |        |  43   | 
+--------------------------------------+

2つのオブジェクト

foo {"title": "test", "id": 42} 
bar {id: 43}

しかし、次のような「AND」クエリは実行できません。

SELECT DISTINCT id  FROM table WHERE title = "test" AND id = 42 

ご覧のとおり、「WHERE」の後の部分はまったくナンセンスですが、自分のやりたいことを実行するクエリを作成する方法がわかりません。

それで、私のデータを保存するより良い方法、または「AND」クエリを実行するための回避策があると思いますか?

そしてもちろん、JSONには任意のプロパティを含めることができるため、プロパティごとに列を持つテーブルを作成することはできません。

私は拡張機能なしのSQLiteであるWebSQLを使用しています。

私の質問はかなり具体的ですが、手伝っていただけませんか。

36
tuxlu

SQLite 3.9では、JSONデータを簡単に操作できる新しい拡張機能( JSON1 )が導入されました。

また、それは expressions のインデックスのサポートを導入しました。これにより、(私の理解では)JSONデータのインデックスも定義できるようになります。

41
ThePhysicist

PostgreSQLには、JSONストレージ用のいくつかの素晴らしい機能があります。あなたはJSON値を選択することができます

SELECT DISTINCT FROM TABLE WHERE foo->title=test AND id=42

jsonbタイプを使用する場合は、JSONオブジェクトの特定のキーにインデックスを付けることもできます。

8

これに対する既存の答えは、OPのデータを実際にJSONとして保存することです(これは彼の根本的な問題に対するより良い解決策であったかもしれません)。

ただし、実際の問題は、複数のプロパティに基づいて、提供されたEAVスタイルのテーブルでドキュメントを検索する方法でした。したがって、おそらくその質問への答えが役に立つでしょう。

あなたが言っていることを行う標準のSQLの方法はINTERSECTIONです。

(SELECT document FROM table WHERE property="id" AND number=43)
INTERSECTION 
(SELECT document FROM table WHERE property="title" AND string="test")

必要に応じて、自己結合を使用してこれを行うこともできます。

SELECT t1.document
FROM table as t1, table as t2
WHERE t1.document = t2.document
AND t1.property="id" AND t1.number=43
AND t2.property="title" AND t2.string="test"

もちろん、より「正しく」、間違いなく最も効率的な方法は、「id」や「title」など、必要な各プロパティの列を作成することです。

5
Thomas Ahle