Filtragem do MongoDB por muitos parâmetros (índice composto ou não)
-
29-10-2019 - |
Pergunta
Tenho um catálogo com produtos e desejo filtrá-lo por vários parâmetros: categoria, preço, tamanho, cor, peso etc.
Portanto, a questão é sobre indexação.
Posso tentar usar o índice composto em todos os campos e consultá-los na mesma ordem em que os indexei. Mas e se eu precisar filtrar apenas por tamanho e cor e apenas por preço e peso? Criar um índice composto para cada consulta de filtragem possível seria um exagero, pois pode haver muitos parâmetros.
Então, depois de alguma pesquisa, encontrei uma abordagem interessante
Sugere-se usar "atributos normalizados":
{color: "red"} = 10
{weight: 125} = 25
{size: "M"} = 30
e agora o registro mongo será parecido com este:
{_id: ..., attributes: [10,25,30]}
Então devo indexar por atributos e depois disso posso consultar desta forma:
db.items.find(attributes: {$all: [10,25,30]})
Advatages são:
- índices menores
- pesquisas mais rápidas
- qualquer número de parâmetros
- crescimento fácil
O que eu não entendi é COMO obtenho esses números para cada atributo? Eles são calculados de alguma forma (como md5)? Ou devo criar uma coleção diferente e armazenar cada número de valor-chave lá? E obter os números a partir daí primeiro - toda vez que eu precisar filtrar a coleção de "itens"?
E o que você acha dessa abordagem?
ATUALIZAÇÃO: E se eu usar strings concatenadas em vez de números?
{_id: ..., attributes: ["language.English", "color.red"]}
Solução
Pesquisar (com eficiência) no catálogo de uma loja é realmente uma tarefa não trivial.
Sim, você pode criar uma coleção adicional e armazenar todos os valores lá
{name: "language", value: "English", numValue: "13"}
Não, você não precisa consultar novamente esta coleção todas as vezes.O tamanho dos dados aqui provavelmente será pequeno, então você pode armazená-los em cache no processo do aplicativo.Não se esqueça da dica: sempre coloque o atributo com a cardinalidade mais baixa primeiro.
Outra abordagem seria usar o mascaramento de bits, mas como o MongoDB tem comprimento de número inteiro limitado, você não pode obter um número ilimitado de atributos.