Tengo una colección como esa:

[
  {
    "query": {
      "filters": {
        "cities": [
          "Warsaw"
        ],
        "universities": [],
        "fieldOfStudyTypes": [],
        
      },
      
    }
  },
  {
    "query": {
      "filters": {
        "cities": [
          "Miami"
        ],
        "universities": [],
        "fieldOfStudyTypes": [],
        
      },
      
    }
  },
  {
    "query": {
      "filters": {
        "cities": [
          "Warsaw",
          "New York"
        ],
        "universities": [],
        "fieldOfStudyTypes": [
          "Computer Science",
          "History"
        ],
        
      },
      
    }
  },
  {
    "query": {
      "filters": {
        "cities": [
          "London"
        ],
        "universities": [],
        "fieldOfStudyTypes": [
          "Computer Science"
        ],
        
      },
      
    }
  },
  {
    "query": {
      "filters": {
        "cities": [
          "Paris"
        ],
        "universities": [],
        "fieldOfStudyTypes": [
          "Computer Science"
        ],
        
      },
      
    }
  },
  {
    "query": {
      "filters": {
        "cities": [
          "Paris"
        ],
        "universities": [],
        "fieldOfStudyTypes": [
          "Computer Science"
        ],
        
      },
      
    }
  }
]

Usando aggregate, me gustaría saber:

  • cuántas veces ocurre una determinada ciudad, universidad o campo de tipo de estudio
  • cuántas veces se produce un determinado fieldOfStudyType con una determinada ciudad

La primera tarea parece bastante sencilla. Por ejemplo, para contar todas las ocurrencias de ciertas ciudades, puedo hacer lo siguiente:

{
  $unwind: '$query.filters.cities',
},
{
  $group: {
    _id: '$query.filters.cities',
     total: { $sum: 1 },
  },
},

Esto produce una salida como esta:

[
  {
    "_id": "London",
    "total": 1
  },
  {
    "_id": "Miami",
    "total": 1
  },
  {
    "_id": "Paris",
    "total": 2
  },
  {
    "_id": "New York",
    "total": 1
  },
  {
    "_id": "Warsaw",
    "total": 2
  }
]

Parece que no puedo averiguar cómo contar las ocurrencias de fieldOfStudyType con una ciudad determinada. Me gustaría tener algo así:

[
  {
    "_id": "London",
    "total": 1,
    "fieldOfStudyTypes": [
      {
        "_id": "Computer Science",
        "total": 1
      }
    ]
  },
  {
    "_id": "Miami",
    "total": 1,
    "fieldOfStudyTypes": []
  },
  {
    "_id": "Paris",
    "total": 2,
    "fieldOfStudyTypes": [
      {
        "_id": "Computer Science",
        "total": 2
      }
    ]
  },
  {
    "_id": "New York",
    "total": 1,
    "fieldOfStudyTypes": [
      {
        "_id": "Computer Science",
        "total": 1
      },
      {
        "_id": "History",
        "total": 1
      }
    ]
  },
  {
    "_id": "Warsaw",
    "total": 2,
    "fieldOfStudyTypes": [
      {
        "_id": "Computer Science",
        "total": 1
      },
      {
        "_id": "History",
        "total": 1
      }
    ],
  }
]
1
Marcin Wanago 24 ago. 2020 a las 17:51

1 respuesta

La mejor respuesta

Puede obtener el resultado esperado de la siguiente consulta. Si necesita seguir los pasos de las universidades también, siga los pasos que he hecho para las ciudades.

[
  {
    $unwind: {
      path: "$query.filters.cities",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $group: {
      _id: "$query.filters.cities",
      total: {
        $sum: 1
      },
      fieldOfStudyTypes: {
        $addToSet: "$query.filters.fieldOfStudyTypes"
      }
    }
  },
  {
    $addFields: {
      fieldOfStudyTypes: {
        $reduce: {
          input: "$fieldOfStudyTypes",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$this",
              "$$value"
            ]
          }
        }
      }
    }
  },
  {
    $unwind: {
      path: "$fieldOfStudyTypes",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $group: {
      _id: "$_id",
      total: {
        $first: "$total"
      },
      fieldOfStudyTypes: {
        $addToSet: {
          $cond: [
            {
              $gt: [
                "$fieldOfStudyTypes",
                null
              ]
            },
            {
              id: "$fieldOfStudyTypes",
              total: {
                $sum: 1
              }
            },
            {}
          ]
        }
      }
    }
  },
  {
    $addFields: {
      fieldOfStudyTypes: {
        $filter: {
          input: "$fieldOfStudyTypes",
          cond: {
            $ne: [
              "$$this",
              {}
            ]
          }
        }
      }
    }
  }
]

Trabajando Monog playground

1
varman 24 ago. 2020 a las 18:04