#artigo
Como uma continuidade do último post sobre PouchDB, nesse artigo iremos aprofundar nas formas de realizar queries no banco de dados. Basicamente existem três formas de realizarmos consultas no PouchDB, uma é através da API allDocs()
e as outras duas são através da API query()
, onde temos as queries temporárias e as queries persistentes.
Utilizando a API allDocs()
sem passar parâmetros nós basicamente estamos buscando por todos os registros de nosso banco de dados. Porém, embora pareça simples, essa API é bastante poderosa, pois ela nos fornece algumas opções para realizar nossas consultas. Dentre elas as que eu mais utilizo são:
include_docs
: caso não seja especificada todos os documentos serão retornados apenas com_id
e_rev
;startkey
&endkey
: busca os documentos cudo IDs estão inclusos no intervalo especificado por essas opções;limit
: número máximo de documentos a ser retornado;skip
: número de documentos que iremos "pular" em nossa consulta;descending
: retorna os documentos em ordem inversa;- para outras opções acesse a documentação do
allDocs()
.
Mas como podemos usar essas opções em nosso favor? Bom, para fazer uma paginação é bem claro que podemos usar as opções limit
e skip
, mas e se eu não quiser que todos os documentos do meu banco de dados sejam retornados, é possível filtrá-los?
Utilizando o startkey
e o endkey
nós podemos buscar apenas os documentos que estão em um determinado intervalo de IDs, certo? Imagine uma situação onde precisamos cadastrar "pessoas" e "empresas" em nosso banco de dados e queremos poder filtrar por cada um desses dois tipos de documentos.Utilizando as opções startkey
e endkey
nós podemos fazer isso desde que a gente defina os IDs de nossos documentos ao invés de deixar que o PouchDB faça isso.
const db = new PouchDB('mydb');
await db.put({
_id: 'pessoa-' + new Date().getTime(),
nome: 'Jean Lucas de Carvalho',
empresa: 'Futuring'
});
await db.put({
_id: 'pessoa-' + new Date().getTime(),
nome: 'Michael Villander',
empresa: 'Front In Brazil'
});
await db.put({
_id: 'empresa-' + new Date().getTime(),
nome: 'Futuring',
cidade: 'Goiânia'
});
No exemplo acima nós criamos nosso banco de dados e cadastramos três documentos nele, dois do tipo "pessoa" e um do tipo "empresa". Agora realizaremos uma consulta utilizando o allDocs()
buscando apenas os documentos com o tipo "pessoa":
db.allDocs({
include_docs: true,
startkey: 'pessoa-',
endkey: 'pessoa-\uffff'
})
.then((result) => {
console.log(result);
})
O exemplo acima nos retornará todos os documentos cujo _id
começa com pessoa-
. Essa consulta funciona graças ao caractere Unicode \uffff
, pois é através dele que nós fazemos buscas por prefixo, ou seja, estamos dizendo ao PouchDB "me retorne todos os documentos cujo _id
começa com pessoa-
".
Essa é uma das formas de definir tipos de documentos no PouchDB, mas as vezes nós não podemos alterar a forma padrão como o banco de dados trata os IDs e pra esses casos uma outra forma bastante usada para definir tipos de documentos é atribuir uma propriedade ao documento especificando seu tipo como veremos na sessão a seguir.
As vezes o allDocs()
não é o suficiente para realizar consultas em nossas aplicações e aí nós precisamos de uma outra API que nos dê mais possibilidades. No PouchDB essa API é o find()
.
Para usar o find()
nós precisamos instalar um módulo chamado pouchdb-find
, podemos fazer isso via script tags ou npm.
<script src=“pouchdb.js”></script>
<script src=“pouchdb.find.js”></script>
npm install --save pouchdb-find
const PouchDB = require('pouchdb');
PouchDB.plugin(require('pouchdb-find'));
Usando nosso exemplo anterior, precisaríamos cadastrar nossos documentos de uma forma diferente:
const db = new PouchDB('mydb');
await db.post({
nome: 'Jean Lucas de Carvalho',
empresa: 'Futuring',
tipo: 'pessoa'
});
await db.post({
nome: 'Michael Villander',
empresa: 'Front In Brazil',
tipo: 'pessoa'
});
await db.post({
nome: 'Futuring',
cidade: 'Goiânia',
tipo: 'empresa'
});
Depois precisaríamos criar um índice:
await db.createIndex({
index: { fields: ['tipo', 'nome'] }
});
E então filtraríamos da seguinte maneira:
db.find({
selector: { tipo: 'pessoa' },
sort: ['tipo', 'nome']
})
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
O find()
possui uma série de seletores para nos ajudar a realizar nossas consultas ($lt
, $gt
, $lte
, $gte
, $eq
, $ne
, $exists
, $in
, etc.). Dessa forma podemos filtrar múltiplos campos de forma muito simples:
db.find({
selector: {
tipo: 'pessoa',
nome: { $regex: new RegExp('^Michael')
},
sort: ['tipo', 'nome']
})
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
O PouchDB ainda possui o query()
como uma outra forma de realizar consultas. Este método utiliza funções map/reduce e consegue atender nos casos onde o find()
não é suficiente. Inclusive, o próprio find()
é uma abstração do query()
para casos comuns.
Não pretendo aprofundar muito nesse método nesse artigo, porém, se os métodos que apresentei anteriormente não forem o suficiente pra você, vale a pena dar uma olhada na documentação.