Ordem de classificação de índices compostos
Nesta página
Os índices armazenam referências a campos em ordem crescente (1
) ou decrescente (-1
). Paraíndices compostos do , a ordem de classificação pode determinar se o índice pode suportar uma operação de classificação.
Os índices compostos permitem operações de classificação que correspondem à ordem de classificação do índice ou à ordem de classificação reversa do índice.
Caso de uso
Um jogo para celular tem uma tabela de classificação que mostra as seguintes informações:
Maiores pontuações do jogo
O usuário que alcançou cada pontuação
A data em que cada pontuação foi obtida
A aplicação classifica o marcador primeiro por score
em ordem decrescente. Em seguida, o username
associado a cada score
é classificado em ordem crescente (alfabeticamente).
Um índice composto pode melhorar o desempenho do marcador se a ordem de classificação no índice corresponder à ordem de classificação na query.
Exemplo
Considere uma coleção leaderboard
com estes documentos:
db.leaderboard.insertMany( [ { "score": 50, "username": "Alex Martin", "date": ISODate("2022-03-01T00:00:00Z") }, { "score": 55, "username": "Laura Garcia", "date": ISODate("2022-03-02T00:00:00Z") }, { "score": 60, "username": "Alex Martin", "date": ISODate("2022-03-03T00:00:00Z") }, { "score": 60, "username": "Riya Patel", "date": ISODate("2022-03-04T00:00:00Z") }, { "score": 50, "username": "Laura Garcia", "date": ISODate("2022-03-05T00:00:00Z") } ] )
Esta query retorna resultados do placar:
db.leaderboard.find().sort( { score: -1, username: 1 } )
Saída:
[ { _id: ObjectId("632235700646eaee87a56a74"), score: 60, username: 'Alex Martin', date: ISODate("2022-03-03T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a75"), score: 60, username: 'Riya Patel', date: ISODate("2022-03-04T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a73"), score: 55, username: 'Laura Garcia', date: ISODate("2022-03-02T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a72"), score: 50, username: 'Alex Martin', date: ISODate("2022-03-01T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a76"), score: 50, username: 'Laura Garcia', date: ISODate("2022-03-05T00:00:00.000Z") } ]
Os resultados são ordenados primeiro por pontuação em ordem decrescente, em seguida por nome de usuário em ordem crescente (alfabeticamente).
Índice de apoio para a tabela de classificação
O índice a seguir melhora o desempenho dos resultados da classificação porque a ordem de classificação do índice corresponde à ordem de classificação usada na query:
db.leaderboard.createIndex( { score: -1, username: 1 } )
Este índice composto armazena:
score
valores em ordem decrescente.username
valores em ordem crescente (alfabeticamente).
Inverter resultados
O MongoDB pode atravessar um índice composto em qualquer direção. Se o aplicativo permitir que os usuários visualizem o placar em ordem inversa, o índice também oferecerá suporte a essa query.
A query a seguir retorna a tabela de classificação em ordem inversa, em que os resultados são classificados primeiro por valores score
ascendentes e depois por valores username
descendentes (em ordem alfabética inversa):
db.leaderboard.find().sort( { score: 1, username: -1 } )
Saída:
[ { _id: ObjectId("632235700646eaee87a56a76"), score: 50, username: 'Laura Garcia', date: ISODate("2022-03-05T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a72"), score: 50, username: 'Alex Martin', date: ISODate("2022-03-01T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a73"), score: 55, username: 'Laura Garcia', date: ISODate("2022-03-02T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a75"), score: 60, username: 'Riya Patel', date: ISODate("2022-03-04T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a74"), score: 60, username: 'Alex Martin', date: ISODate("2022-03-03T00:00:00.000Z") } ]
O índice { score: -1, username: 1 }
oferece apoio para esta query.
Queries não suportadas
Os índices compostos não podem suportar queries onde a ordem de classificação não corresponde ao índice ou ao inverso do índice. Como resultado, o índice { score:
-1, username: 1 }
não pode suportar uma classificação por valores score
crescentes e, em seguida, por valores username
crescentes, como nesta query:
db.leaderboard.find().sort( { score: 1, username: 1 } )
Além disso, para que uma operação de classificação use um índice, os campos especificados na classificação devem aparecer na mesma ordem em que aparecem em um índice. Como resultado, o índice acima não pode suportar esta query:
db.leaderboard.find().sort( { username: 1, score: -1, } )
Saiba mais
Para obter mais informações sobre ordem de classificação e índices, consulte Usar índices para classificar resultados da query.
Para mais informações sobre classificação de resultados de query, consulte
sort()
.