sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB ordena documentos por elementos de matriz

No puede hacer eso con matrices, y el principal problema aquí es porque desea que la "clasificación" ocurra en el elemento coincidente. Si desea ordenar resultados como este, debe usar .aggregate() en cambio. Ya sea como:

Para versiones modernas de MongoDB:

db.maps.aggregate([
    { "$match": { "points.type": "type1" }},
    { "$addFields": {
        "order": {
            "$filter": {
              "input": "$points",
              "as": "p",
              "cond": { "$eq": [ "$$p.type", "type1" ] }
            }
        }
    }},
    { "$sort": { "order": 1 } }
])

Para MongoDB 2.6 a 3.0

db.maps.aggregate([
   { $match: { 'points.type': 'type1' } },
    {
     $project: {
       points: {
        $setDifference: [
          {
            $map: {
              input: '$points',
              as: 'p',
              in: {
                $cond: [
                  { $eq: ['$$p.type', 'type1'] },
                  '$$p',
                  false,
                ]
              }
            }
          },
          [false]
        ]
      }
    }
  },
  { $sort: { 'points.distanceToSpawn': 1 } },
]);

O menos eficiente en versiones anteriores a MongoDB 2.6:

db.maps.aggregate([
    { "$match": { "points.type": "type1" }},
    { "$unwind": "$points" },
    { "$match": { "points.type": "type1" }},
    { "$group": {
        "_id": "$_id",
        "points": { "$push": "$points" }
    }},
    { "$sort": { "points.ditanceToSpawn": 1 } }         
])

Esa es la única forma de hacer coincidir los elementos correctos y tenerlos en cuenta en una operación de "clasificación". De lo contrario, la clasificación de cursor predeterminada considerará los valores para el campo en los elementos de la matriz que no coinciden con el "tipo" seleccionado.