J'ai besoin de stocker des objets JSON dans une base de données SQLite, puis de faire des requêtes complexes dessus.
J'ai fait un tableau comme celui-ci:
+--------------------------------------+
|document | property | string | number|
+--------------------------------------+
|foo | "title" | "test" | |
+--------------------------------------+
|foo | "id" | | 42 |
+--------------------------------------+
|bar | "id" | | 43 |
+--------------------------------------+
pour les deux objets
foo {"title": "test", "id": 42}
bar {id: 43}
Mais je ne peux pas faire de requêtes "ET", comme:
SELECT DISTINCT id FROM table WHERE title = "test" AND id = 42
comme vous le voyez, la partie après le "WHERE" est un non-sens total, mais je n'ai aucune idée de la façon de créer une requête qui ferait ce que je veux.
Pensez-vous donc qu'il existe un meilleur moyen de stocker mes données, ou une solution de contournement pour effectuer une requête "ET"?
Et bien sûr, le JSON peut contenir n'importe quelle propriété, donc je ne peux pas créer une table avec des colonnes pour chaque propriété.
J'utilise WebSQL, qui est SQLite sans extensions.
Je sais que ma question est assez précise, mais pourriez-vous m'aider?
SQLite 3.9 a introduit une nouvelle extension ( JSON1 ) qui vous permet de travailler facilement avec des données JSON.
En outre, il a introduit la prise en charge des index sur expressions , ce qui (à ma connaissance) devrait également vous permettre de définir des index sur vos données JSON.
PostgreSQL a quelques fonctionnalités intéressantes pour le stockage JSON. Vous pouvez sélectionner les valeurs JSON en faisant
SELECT DISTINCT FROM TABLE WHERE foo->title=test AND id=42
Vous pouvez également indexer les clés spécifiques sur l'objet JSON si vous utilisez le type jsonb
.
Les réponses existantes à ce problème concernent le stockage des données de l'OP au format JSON (ce qui pourrait être une meilleure solution à son problème sous-jacent).
Cependant, la vraie question était de savoir comment obtenir des documents dans le tableau de style EAV fourni, en fonction de plusieurs propriétés. Une réponse à cette question serait donc peut-être utile.
La façon SQL standard de faire ce que vous dites est INTERSECTION.
(SELECT document FROM table WHERE property="id" AND number=43)
INTERSECTION
(SELECT document FROM table WHERE property="title" AND string="test")
Vous pouvez également le faire avec des auto-jointures si vous préférez.
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"
Bien sûr, le moyen le plus "correct" et sans doute le plus efficace serait de créer une colonne pour chaque propriété dont vous avez besoin, comme "id" et "title".