É possível armazenar e consultar JSON no SQLite?

35

Preciso armazenar objetos JSON em um banco de dados SQLite e fazer consultas complexas nele.

Eu fiz uma tabela como esta:

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

para os dois objetos

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

Mas não posso fazer consultas "AND", como:

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

como você vê, a parte após o "WHERE" é totalmente sem sentido, mas não tenho idéia de como criar uma consulta que faria o que eu quero.

Então, você acha que existe uma maneira melhor de armazenar meus dados ou uma solução alternativa para fazer uma consulta "AND"?

E, é claro, o JSON pode conter qualquer propriedade, portanto, não posso criar uma tabela com colunas para cada propriedade.

Estou usando o WebSQL, que é SQLite sem extensões.

Sei que minha pergunta é bem específica, mas você poderia me ajudar?

tuxlu
fonte
2
Se isso é realmente importante para o seu aplicativo, provavelmente é melhor usar um repositório de documentos real ("NoSQL") ou, por exemplo, mudar para o Postgres, que combina armazenamento JSON muito eficiente com fortes recursos relacionais.
a_horse_with_no_name
3
Leia a documentação .
CL.
@CL. Yupp. Isso também é o primeiro resultado quando googling para "sqlite json" :)
Izzy
Você precisa contas e deve mesclá-las: dba.stackexchange.com/users/81459/tuxlu e dba.stackexchange.com/users/81513/tuxlu Você pode usar esta página de ajuda: dba.stackexchange.com/help/merging-accounts
Julien Vavasseur
@ Izzy Primeiro de tudo, para mim, pelo menos, esta pergunta é agora o primeiro resultado, não os documentos. Em segundo lugar, essa extensão não é uma boa resposta para o OP, que declarou explicitamente usando 'WebSQL, que é SQLite sem extensões'.
OJFord 8/09/18

Respostas:

35

O SQLite 3.9 introduziu uma nova extensão ( JSON1 ) que permite trabalhar facilmente com dados JSON.

Além disso, ele introduziu suporte para índices de expressões , o que (no meu entendimento) deve permitir que você defina índices nos seus dados JSON também.

ThePhysicist
fonte
7

O PostgreSQL possui alguns recursos interessantes para armazenamento JSON. Você pode selecionar os valores JSON fazendo

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

Você também pode indexar as chaves específicas no objeto JSON se você usar o jsonbtipo

redneckProgrammer
fonte
5

As respostas existentes para esse acordo realmente armazenam os dados do OP como JSON (que pode ter sido uma solução melhor para o problema subjacente).

No entanto, a questão real era como encontrar documentos na tabela de estilo EAV fornecida, com base em várias propriedades. Portanto, talvez uma resposta para essa pergunta seja útil.

A maneira padrão do SQL de fazer o que você está dizendo é INTERSECTION.

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

Você também pode fazer isso com auto-junções, se preferir.

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"

É claro que a maneira mais "correta" e sem dúvida mais eficiente seria criar uma coluna para cada propriedade necessária, como 'id' e 'title'.

Thomas Ahle
fonte