Você pode pensar no índice de campo único do MongoDB como uma matriz, com ponteiros para locais de documentos. Por exemplo, se você tiver uma coleção com (observe que a sequência está deliberadamente fora de ordem):
[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}
Índice de campo único
Agora se você fizer:
db.collection.createIndex({a:1})
O índice se parece aproximadamente com:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Observe três coisas importantes:
- É classificado por
aascendente - Cada entrada aponta para o local onde residem os documentos relevantes
- O índice registra apenas os valores do
acampo. Obcampo não existe no índice de forma alguma
Então, se você fizer uma consulta como:
db.collection.find().sort({a:1})
Tudo o que ele precisa fazer é percorrer o índice de cima para baixo, buscando e exibindo o documento apontado pelas entradas. Observe que você também pode percorrer o índice de baixo para cima, por exemplo:
db.collection.find().sort({a:-1})
e a única diferença é que você anda o índice ao contrário.
Porque
b não está no índice, você não pode usar o índice ao consultar qualquer coisa sobre b . Índice composto
Em um índice composto, por exemplo:
db.collection.createIndex({a:1, b:1})
Isso significa que você deseja classificar por
a primeiro, depois classifique por b . O índice ficaria assim:[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1
Observe que:
- O índice é classificado de
a - Em cada
avocê tem umbordenado - Você tem 5 entradas de índice contra apenas três no exemplo anterior de campo único
Usando este índice, você pode fazer uma consulta como:
db.collection.find({a:2}).sort({b:1})
Ele pode encontrar facilmente onde
a:2 em seguida, caminhe o índice para a frente. Dado esse índice, você não pode fazer :db.collection.find().sort({b:1})
db.collection.find({b:1})
Em ambas as consultas, você não pode encontrar facilmente
b uma vez que está espalhado por todo o índice (ou seja, não em entradas contíguas). No entanto, você pode Faz:db.collection.find({a:2}).sort({b:-1})
já que você pode encontrar essencialmente onde o
a:2 são, e percorra o b entradas para trás. Editar :esclarecimento da pergunta do @marcospgp no comentário:
A possibilidade de usar o índice
{a:1, b:1} para satisfazer find({a:2}).sort({b:-1}) realmente faz sentido se você vê-lo do ponto de vista de uma tabela classificada. Por exemplo, o índice {a:1, b:1} pode ser pensado como:a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
localizar({a:2}).sort({b:1})
O índice
{a:1, b:1} significa sort by a, then within each a, sort the b values . Se você fizer um find({a:2}).sort({b:1}) , o índice sabe onde estão todos os a=2 são. Dentro deste bloco de a=2 , o b seria classificada em ordem crescente (de acordo com a especificação do índice), de modo que a consulta find({a:2}).sort({b:1}) pode ser satisfeita por:a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2
localizar({a:2}).sort({b:-1})
Como o índice pode ser andado para frente ou para trás, um procedimento semelhante foi seguido, com uma pequena torção no final:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block backward to satisfy
2 | 2 <-- find({a:2}).sort({b:-1})
2 | 3 <--
3 | 1
3 | 2
O fato de o índice poder avançar ou retroceder é o ponto chave que habilita a consulta
find({a:2}).sort({b:-1}) para poder usar o índice {a:1, b:1} . Explicação do planejador de consultas
Você pode ver o que o planejador de consultas planeja usando
db.collection.explain().find(....) . Basicamente, se você vir um stage de COLLSCAN , nenhum índice foi usado ou pode ser usado para a consulta. Consulte explicar resultados
para obter detalhes sobre a saída do comando.