sql >> Databasteknik >  >> NoSQL >> MongoDB

Partitionera data runt en matchningsfråga under aggregering

Denna aggregering ger önskat resultat.

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 } }
] )


[ REDIGERA LÄGG TILL ]

Utdata från frågan med hjälp av indata från frågeposten:

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


[REDIGERA LÄGG TILL 2]

Den här frågan får samma resultat med olika tillvägagångssätt (kod):

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 
      } 
  }
] )


[ EDIT ADD 3 ]

OBS:

Fasettfrågan kör de två aspekterna (TRUE och FALSE) på samma uppsättning dokument; det är som två frågor som körs parallellt. Men det finns en del dubblering av kod såväl som ytterligare steg för att forma dokumenten längs pipelinen för att få önskad utdata.

Den andra frågan undviker kodduplicering, och det finns mycket mindre stadier i aggregeringspipelinen. Detta kommer att göra skillnad när indatadataset har ett stort antal dokument att bearbeta - vad gäller prestanda. I allmänhet betyder mindre stadier färre iterationer av dokumenten (eftersom ett steg måste skanna de dokument som matas ut från föregående steg).




  1. Datetime-problem med Mongo och C#

  2. Bästa sättet att lagra datum/tid i mongodb

  3. hur man använder mongoimport för att importera en json-fil

  4. Sortera en kapslad array i mongoose