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

Partición de datos en torno a una consulta de coincidencia durante la agregación

Esta agregación da el resultado deseado.

db.posts.aggregate( [
{ $match:  { updatedAt: { $gte: 1549786260000 } } },
{ $facet: {
        FALSE: [
            { $match: { toggle: false } },
            { $unwind : "$interests" },
            { $group : { _id : { iid: "$interests", pid: "$publisher" }, count: { $sum : 1 } } },
        ],
        TRUE: [
            { $match: { toggle: true, status: "INACTIVE" } },
            { $unwind : "$interests" },
            { $group : { _id : { iid: "$interests", pid: "$publisher" }, count: { $sum : -1 } } },
        ]
} },
{ $project: { result: { $concatArrays: [ "$FALSE", "$TRUE" ] } } },
{ $unwind: "$result" },
{ $replaceRoot: { newRoot: "$result" } },
{ $group : { _id : "$_id", count: { $sum : "$count" } } },
{ $project:{ _id: 0, iid: "$_id.iid", pid: "$_id.pid", count: 1 } }
] )


[ EDITAR AGREGAR ]

El resultado de la consulta utilizando los datos de entrada de la publicación de la pregunta:

{ "count" : 1, "iid" : "INT123", "pid" : "P789" }
{ "count" : 1, "iid" : "INT123", "pid" : "P123" }
{ "count" : 0, "iid" : "INT789", "pid" : "P789" }
{ "count" : 1, "iid" : "INT456", "pid" : "P789" }


[EDITAR AÑADIR 2]

Esta consulta obtiene el mismo resultado con un enfoque diferente (código):

db.posts.aggregate( [
  { 
      $match:  { updatedAt: { $gte: 1549786260000 } } 
  },
  { 
      $unwind : "$interests" 
  },
  { 
      $group : { 
          _id : { 
              iid: "$interests", 
              pid: "$publisher" 
          }, 
          count: { 
              $sum: {
                  $switch: {
                      branches: [
                        { case: { $eq: [ "$toggle", false ] },
                           then: 1 },
                        { case: { $and: [ { $eq: [ "$toggle", true] },  { $eq: [ "$status", "INACTIVE" ] } ] },
                           then: -1 }
                      ]
                  }          
              } 
          }
      } 
  },
  { 
      $project:{
           _id: 0, 
           iid: "$_id.iid", 
           pid: "$_id.pid", 
           count: 1 
      } 
  }
] )


[ EDITAR AÑADIR 3 ]

NOTA:

La consulta de facetas ejecuta las dos facetas (VERDADERO y FALSO) en el mismo conjunto de documentos; es como dos consultas que se ejecutan en paralelo. Sin embargo, hay cierta duplicación de código, así como etapas adicionales para dar forma a los documentos a lo largo de la canalización para obtener el resultado deseado.

La segunda consulta evita la duplicación de código y hay etapas mucho menores en la canalización de agregación. Esto marcará la diferencia cuando el conjunto de datos de entrada tenga una gran cantidad de documentos para procesar, en términos de rendimiento. En general, las etapas menores significan iteraciones menores de los documentos (ya que una etapa tiene que escanear los documentos que se generan en la etapa anterior).