Tengo esta operación de agregación y me está dando el resultado correcto, pero con un orden inconsistente. Cuando recargo, la matriz de salida anidada (posteriorThread) cambia el orden de los documentos, ¡y parece que no hay rima ni razón!

Estoy confundido por qué el orden sigue cambiando y me gustaría saber por qué está sucediendo, pero pensé que simplemente lo ordenaría, lo cual hice, pero tengo problemas para agruparlo nuevamente.

Le mostraré mis dos soluciones rotas a continuación, pero esencialmente quiero la salida 1 pero con el orden correcto. Estoy usando mangosta, pero eso no debería marcar la diferencia.

Gracias.

1: Solución de pedido inconsistente

const posteriorThread = await Comment.aggregate([
      {
        $match: {
          _id: post.threadDescendant,
        },
      },
      {
        $graphLookup: {
          from: 'comments',
          startWith:'$threadDescendant',
          connectFromField: 'threadDescendant',
          connectToField: '_id',
          as: 'posteriorThread',
        },
      },
    ]);

SALIDA: 1


posteriorThread [
  {
    "_id": "000",
    "name": "foo bar",
    "text": "testing one",
    "threadDescendant": "123",
    "posteriorThread": [
      {
        "_id": "234",
        "name": "foo bar",
        "text": "testing four",
        "threadDescendant": "345"
      },
      {
        "_id": "345",
        "name": "foo bar",
        "text": "testing three",
      }, 
      {
        "_id": "123",
        "name": "foo bar",
        "text": "testing two",
        "threadDescendant": "234"
      },  
    ]
  }
]

2: Corrija el documento raíz anterior pero pierda

    const posteriorThread = await Comment.aggregate([
      {
        $match: {
          _id: post.threadDescendant,
        },
      },
      {
        $graphLookup: {
          from: 'comments',
          startWith: '$threadDescendant',
          connectFromField: 'threadDescendant',
          connectToField: '_id',
          as: 'posteriorThread',
        },
      },
      {
        $unwind: '$posteriorThread',
      },
      {
        $sort: { 'posteriorThread.depth': 1 },
      },
      {
        $group: { _id: '$_id', posteriorThread: { $push: '$posteriorThread' } },
      },
    ]);

SALIDA 2:

posteriorThread [
  {
    "_id": "000",
    "posteriorThread": [
      {
        "_id": "123",
        "name": "foo bar",
        "text": "testing two",
        "threadDescendant": "234"
      },  
      {
        "_id": "234",
        "name": "foo bar",
        "text": "testing four",
        "threadDescendant": "345"
      },
      {
        "_id": "345",
        "name": "foo bar",
        "text": "testing three",
      }, 
    ]
  }
]
1
ram 29 jul. 2020 a las 12:04

1 respuesta

La mejor respuesta

La etapa de canalización $graphLookup no ofrece ninguna capacidad de clasificación incorporada, por lo que su segundo enfoque es correcto. Solo necesita usar $ first para preservar el objeto raíz campos. Puede usar $ replaceRoot y la variable especial $$ROOT para evitar especificar cada campo explícitamente:

{
    $group: {
        _id: "$_id",
        posteriorThread: { $push: "$posteriorThread" },
        root: { $first: "$$ROOT" }
    }
},
{
    $project: {
        "root.posteriorThread": 0
    }
},
{
    $replaceRoot: {
        newRoot: {
            $mergeObjects: [
                { posteriorThread: "$posteriorThread" },
                "$root"
            ]
        }
    }
}

Parque infantil Mongo

1
mickl 29 jul. 2020 a las 10:22