A primeira coisa que vem à mente aqui é:por que armazenar uma referência custa 5.000 vezes o que custa armazenar em um subdocumento?
Ok, olhando para o seu esquema, acredito que o melhor método é a coleta separada de palavras, não de pacotes.
A primeira bandeira vermelha que vi é o seu aninhamento duplo aqui:
packages : [{
package : {type: Schema.Types.ObjectId, ref: 'Packages'},
from : {type : Schema.Types.ObjectId, ref :'Languages'},
to : {type : Schema.Types.ObjectId, ref :'Languages'},
words : [{
word: {type: String},
progress: {type: Number,default : 0}
}]
}]
As
words
será muito difícil trabalhar com o subdocumento na versão atual do MongoDB, normalmente 2-3 níveis de profundidade começam a ter problemas, especialmente com operadores posicionais. Agora, considerando que você deve sempre trabalhar com o valor mais alto possível, você pode obter aqui:
Você também deve considerar o custo de hospedagem deste documento. Os operadores necessários serão aqueles na memória, como
$pull
, $push
, $addToSet
etc, o que significa que todo o seu documento precisará ser serializado e carregado nas estruturas C++ nativas do MongoDB. Esta será uma tarefa extremamente demorada, dependendo do tráfego para esses documentos. Considerando seu comentário:
ele simplesmente coloca outro prego no caixão de incorporar as palavras no documento principal do usuário. Considerando o que eu disse no parágrafo anterior, isso não funcionará bem com o custo de usar operadores de memória nas
words
variedade. Isso funcionará muito melhor se as palavras forem divididas,
$slice
também é um operador in-memory e provavelmente sofreria um desempenho reduzido aqui. E essa é uma resposta rápida e racional. Tenho certeza de que há mais coisas que eu poderia explicar sobre minha razão, mas isso deve ser suficiente.