Targeted Queries | Shards | MongoDB | Banco de dados
- Targeted Queries | Shards | MongoDB | Banco de dados
Targeted queries no MongoDB
Targeted queries são consultas que, em um cluster sharded, conseguem ser roteadas pelo mongos para um shard específico ou para um conjunto pequeno de shards.
Isso acontece quando a query usa a shard key no filtro, principalmente quando usa o prefixo da shard key composta.
Em sharding, o mongos é o roteador da consulta. Ele analisa o filtro da query e decide para quais shards a operação precisa ser enviada. O tema aparece dentro de sharding como parte de “querying sharded data”, “query router” e escolha correta da shard key.
Exemplo com shard key simples
sh.shardCollection("loja.pedidos", { clienteId: 1 })
Query targeted:
db.pedidos.find({
clienteId: 123
})
Aqui o MongoDB consegue rotear a consulta usando clienteId, que é a shard key.
Query não targeted:
db.pedidos.find({
status: "PENDENTE"
})
Como status não é a shard key, o mongos não sabe em qual shard procurar. Então ele pode consultar todos os shards. Isso é chamado de scatter-gather.
Shard key composta
Se no método find() as shards key estiverem invertidas, mas conterem todas, o mongo reorganiza e é uma boa query
{ "airline_id" : 1, "departure_airport" : 1 }
db.flights.find( { airline_id: 2946863 } )
db.flights.find( { departure_airport: "JFK", airline_id: 2946863 } )
db.flights.find( { airline_id: 2946863, departure_airport: "JFK" } )
Uma shard key composta usa mais de um campo para distribuir os documentos.
Exemplo:
sh.shardCollection("loja.pedidos", {
clienteId: 1,
dataPedido: 1
})
Aqui a shard key é composta por:
clienteId + dataPedido
A ordem importa.
O primeiro campo, clienteId, é o prefixo da shard key.
Exemplo 1: usando o primeiro campo da shard key
db.pedidos.find({
clienteId: 123
})
Essa query tende a ser targeted, porque usa o primeiro campo da shard key composta.
Mesmo sem informar dataPedido, o MongoDB já consegue restringir a busca aos chunks relacionados ao clienteId.
Exemplo 2: usando a shard key completa
db.pedidos.find({
clienteId: 123,
dataPedido: ISODate("2026-05-21")
})
Essa é ainda melhor.
Aqui a query usa os dois campos da shard key:
clienteId + dataPedido
O mongos consegue rotear a consulta com mais precisão.
Exemplo 3: usando range no segundo campo
db.pedidos.find({
clienteId: 123,
dataPedido: {
$gte: ISODate("2026-05-01"),
$lt: ISODate("2026-06-01")
}
})
Também pode ser targeted, porque usa o prefixo clienteId.
O segundo campo, dataPedido, ajuda a limitar ainda mais a busca.
Exemplo 4: usando apenas o segundo campo
db.pedidos.find({
dataPedido: ISODate("2026-05-21")
})
Essa query não é boa para roteamento.
Mesmo dataPedido fazendo parte da shard key, ele não é o primeiro campo. Como a shard key é:
{
clienteId: 1,
dataPedido: 1
}
o MongoDB precisa primeiro de clienteId para conseguir rotear bem.
Ou seja: usar apenas dataPedido pode virar scatter-gather.
Exemplo 5: shard key composta com região e cliente
sh.shardCollection("loja.pedidos", {
regiao: 1,
clienteId: 1
})
Boa query:
db.pedidos.find({
regiao: "SP"
})
Targeted ou parcialmente targeted, porque usa o primeiro campo da shard key.
Melhor query:
db.pedidos.find({
regiao: "SP",
clienteId: 123
})
Mais precisa, porque usa a shard key completa.
Query ruim:
db.pedidos.find({
clienteId: 123
})
Apesar de clienteId fazer parte da shard key, ele não é o primeiro campo. Como falta regiao, o roteamento fica pior.
Exemplo 6: shard key composta com tenant
Muito comum em sistemas multi-tenant:
sh.shardCollection("app.eventos", {
tenantId: 1,
criadoEm: 1
})
Boa query:
db.eventos.find({
tenantId: "empresa-001"
})
Melhor:
db.eventos.find({
tenantId: "empresa-001",
criadoEm: {
$gte: ISODate("2026-05-01"),
$lt: ISODate("2026-06-01")
}
})
Ruim:
db.eventos.find({
criadoEm: {
$gte: ISODate("2026-05-01")
}
})
Sem tenantId, o MongoDB pode precisar consultar vários shards.
Resumo prático
| Query | Shard key | Targeted? | Motivo |
|---|---|---|---|
{ clienteId: 123 } | { clienteId: 1 } | Sim | Usa a shard key |
{ status: "PENDENTE" } | { clienteId: 1 } | Não | Não usa a shard key |
{ clienteId: 123 } | { clienteId: 1, dataPedido: 1 } | Sim | Usa o prefixo da shard key |
{ clienteId: 123, dataPedido: ... } | { clienteId: 1, dataPedido: 1 } | Sim | Usa a shard key completa |
{ dataPedido: ... } | { clienteId: 1, dataPedido: 1 } | Geralmente não | Não usa o prefixo inicial |
{ regiao: "SP" } | { regiao: 1, clienteId: 1 } | Sim | Usa o primeiro campo |
{ clienteId: 123 } | { regiao: 1, clienteId: 1 } | Geralmente não | Pula o primeiro campo |
Regra de ouro
Para uma query ser bem direcionada em shard key composta, ela deve usar o primeiro campo da shard key.
Shard key composta:
{ A: 1, B: 1, C: 1 }
Boas queries:
{ A: ... }
{ A: ..., B: ... }
{ A: ..., B: ..., C: ... }
Queries ruins para roteamento:
{ B: ... }
{ C: ... }
{ B: ..., C: ... }
Ou seja:
Tem o prefixo da shard key = tende a ser targeted
Não tem o prefixo da shard key = tende a ser scatter-gather