Como o MongoDB classifica os registros quando nenhuma ordem de classificação é especificada?

103

Quando executamos uma consulta find () do Mongo sem nenhuma ordem de classificação especificada, o que o banco de dados usa internamente para classificar os resultados?

De acordo com a documentação no site do mongo :

Ao executar um find () sem parâmetros, o banco de dados retorna objetos em ordem natural direta.

Para tabelas padrão, a ordem natural não é particularmente útil porque, embora a ordem geralmente esteja próxima da ordem de inserção, não é garantido que seja. No entanto, para coleções limitadas, a ordem natural é garantida como o pedido de inserção. Isso pode ser muito útil.

No entanto, para coleções padrão (coleções sem limite), qual campo é usado para classificar os resultados? É o campo _id ou algo mais?

Editar:

Basicamente, acho que o que estou tentando chegar é se eu executar a seguinte consulta de pesquisa:

db.collection.find({"x":y}).skip(10000).limit(1000);

Em dois momentos diferentes: t1 e t2 , irei obter conjuntos de resultados diferentes:

  1. Quando não houve gravações adicionais entre t1 e t2?
  2. Quando houve novas gravações entre t1 e t2?
  3. Existem novos índices que foram adicionados entre t1 e t2?

Eu executei alguns testes em um banco de dados temporário e os resultados que obtive são os mesmos ( Sim ) para todos os 3 casos - mas eu queria ter certeza e tenho certeza de que meus casos de teste não foram muito completos.

saurabhj
fonte

Respostas:

121

Qual é a ordem de classificação padrão quando nenhuma é especificada?

A ordem de classificação interna padrão (ou ordem natural ) é um detalhe de implementação indefinido . Manter a ordem é uma sobrecarga extra para os mecanismos de armazenamento e a API do MongoDB não exige previsibilidade fora de um caso explícito sort()ou especial de coleções limitadas de tamanho fixo que têm restrições de uso associadas . Para cargas de trabalho típicas, é desejável que o mecanismo de armazenamento tente reutilizar o espaço pré-alocado disponível e tome decisões sobre como armazenar dados de forma mais eficiente no disco e na memória.

Sem nenhum critério de consulta, os resultados serão retornados pelo mecanismo de armazenamento em ordem natural (ou seja, na ordem em que são encontrados ). A ordem dos resultados pode coincidir com a ordem de inserção, mas esse comportamento não é garantido e não pode ser confiável (exceto coleções limitadas).

Alguns exemplos que podem afetar a ordem (natural) de armazenamento:

  • O WiredTiger usa uma representação diferente de documentos no disco em comparação com o cache na memória, portanto, a ordem natural pode mudar com base nas estruturas de dados internas.
  • O mecanismo de armazenamento MMAPv1 original (removido no MongoDB 4.2) aloca espaço de registro para documentos com base em regras de preenchimento. Se um documento ultrapassar o espaço de registro atualmente alocado, a localização do documento (e a ordem natural) serão afetadas. Novos documentos também podem ser inseridos no armazenamento marcado como disponível para reutilização devido a documentos excluídos ou movidos.
  • A replicação usa um formato de oplog idempotente para aplicar operações de gravação de forma consistente nos membros do conjunto de réplicas. Cada membro do conjunto de réplicas mantém arquivos de dados locais que podem variar em ordem natural, mas terão o mesmo resultado de dados quando as atualizações de oplog forem aplicadas.

E se um índice for usado?

Se um índice for usado, os documentos serão retornados na ordem em que foram encontrados (o que necessariamente corresponde ao pedido de inserção ou ordem de E / S). Se mais de um índice for usado, a ordem dependerá internamente de qual índice identificou o documento pela primeira vez durante o processo de eliminação de duplicação.

Se desejar uma ordem de classificação previsível, você deve incluir um explícito sort()em sua consulta e ter valores exclusivos para sua chave de classificação.

Como as coleções limitadas mantêm a ordem de inserção?

A exceção de implementação observada para a ordem natural em coleções limitadas é reforçada por suas restrições especiais de uso: os documentos são armazenados na ordem de inserção, mas o tamanho do documento existente não pode ser aumentado e os documentos não podem ser explicitamente excluídos. O pedido é parte do design da coleção limitada que garante que os documentos mais antigos "envelheçam" primeiro.

Stennie
fonte
4
Então, isso significa que se eu executar o mesmo comando find: db.collection.find ({"x": y}). Skip (20000) .limit (1000) em dois pontos diferentes no tempo, obterei resultados diferentes conjuntos? O que acontece se não houver gravações entre os dois comandos?
saurabhj
6
@saurabhj: Adicionados alguns exemplos que afetarão a ordem natural. Se os documentos foram movidos / excluídos, você pode obter conjuntos de resultados diferentes. Se não houver inserções / atualizações / exclusões de documentos, você deverá obter o mesmo resultado. Adicionar índices não afeta a localização dos documentos no disco.
Stennie
7
Também deve adicionar a advertência de que, se você estiver usando replicação, a ordem natural pode variar entre os membros do conjunto de réplicas.
Stennie
Alguém sabe forçar algum dos 2 pontos comentados aqui? Tentamos modificar os documentos, mas eles ainda retornam com o pedido de inserção ... Estou curioso para saber se a ordem natural pode ser diferente do pedido de inserção.
Ferran Maylinch
Impor uma ordem padrão (por exemplo {createdAt: -1}) é necessário para implementar padrões de UI otimistas (atualizar listas de dados no cache sem esperar pela resposta do servidor após criar / atualizar / excluir). Caso contrário, você não pode combinar a ordem otimista do lado do cliente e a ordem de resposta do servidor.
Eric Burel
8

Ele é retornado na ordem armazenada (ordem no arquivo), mas não é garantido que eles estejam na ordem inserida. Eles não são classificados pelo campo _id. Às vezes, pode parecer que está classificado pelo pedido de inserção, mas pode ser alterado em outra solicitação. Não é confiável.

Parvin Gasimzade
fonte