MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

classificação de subdocumentos mangusto


Eu poderia ter escrito isso como algumas coisas, mas considerando "recuperar os objetos mangustos" parece ser a principal consideração.

Portanto, há várias coisas que você "poderia" fazer. Mas como você está "preenchendo referências" em um objeto e, em seguida, deseja alterar a ordem dos objetos em uma matriz, realmente há apenas uma maneira de corrigir isso de uma vez por todas.

Corrija os dados na ordem em que os cria


Se você deseja que sua matriz "comentários" seja classificada pela data em que são "criados_at", isso se divide em várias possibilidades:

  1. Ele "deveria" ter sido adicionado na ordem de "inserção", então o "mais recente" é o último, como você observa, mas você também pode "modificar" isso nas versões recentes (últimos dois anos) do MongoDB com $position como um modificador para $push :
    Article.update(
        { "_id": articleId },
        { 
            "$push": { "comments": { "$each": [newComment], "$position": 0 } }
        },
        function(err,result) {
            // other work in here
        }
    );
    

    Isso "anexe" o elemento da matriz à matriz existente no "primeiro" (0) índice para que esteja sempre na frente.

  2. Falhando ao usar atualizações "posicionais" por razões lógicas ou apenas onde você "quer ter certeza", então existe há um tempo ainda "mais longo" o $sort modificador para $push :
    Article.update(
        { "_id": articleId },
        { 
            "$push": { 
                "comments": { 
                    "$each": [newComment], 
                    "$sort": { "$created_at": -1 } 
                }
            }
        },
        function(err,result) {
            // other work in here
        }
    );
    

    E isso irá "classificar" na propriedade dos documentos de elementos da matriz que contém o valor especificado em cada modificação. Você pode até fazer:
    Article.update(
        {  },
        { 
            "$push": { 
                "comments": { 
                    "$each": [], 
                    "$sort": { "$created_at": -1 } 
                }
            }
        },
        { "multi": true },
        function(err,result) {
            // other work in here
        }
    );
    

    E isso classificará cada array de "comentários" em toda a sua coleção pelo campo especificado em um hit.

Outras soluções são possíveis usando .aggregate() para ordenar o array e/ou "re-casting" para objetos mangusto depois de ter feito essa operação ou depois de fazer seu próprio .sort() no objeto simples.

Ambos realmente envolvem a criação de um objeto de modelo separado e "esquema" com os itens incorporados, incluindo as informações "referenciadas". Portanto, você pode trabalhar nessas linhas, mas parece ser uma sobrecarga desnecessária quando você pode apenas classificar os dados para os meios "mais necessários" em primeiro lugar.

A alternativa é garantir que campos como "virtuais" sempre "serializem" em um formato de objeto com .toObject() de plantão e apenas viver com o fato de que todos os métodos desapareceram agora e funcionam com as propriedades apresentadas.

A última é uma abordagem "sã", mas se o que você normalmente usa é a ordem "created_at", faz muito mais sentido "armazenar" seus dados dessa maneira com cada operação, para que, quando você os "recupere", eles permaneçam no ordem que você vai usar.