2017-01-11 6 views
3

Ich habe folgende mongodb Aggregatabfrage, die Gruppe nach Datum (2017.01.05 bis 1-13-2017)Wie kann ich ein neues Feld zum Mongo-Gesamtergebnis hinzufügen?

CampaignActivity.aggregate([ 
     { 
     "$match": { 
      "$and":[{updatedAt: {$lt: new Date('1-13-2017')}},{updatedAt: {$gte: new Date('1-05-2017')}}] 
     } 
    }, 
    { 
     "$project" : 
     { 
      _id : 0, 
      "datePartDay" : {"$concat" : [ 
       {"$substr" : [{"$dayOfMonth" : "$updatedAt"}, 0, 2]}, "-", 
       {"$substr" : [{"$month" : "$updatedAt"}, 0, 2]}, "-", 
       {"$substr" : [{"$year" : "$updatedAt"}, 0, 4]} 
      ] }, 
      "isdelivered": {"$cond": { if: { $eq: [ "$delivered", true ] }, then: 1, else: 0 }}, 
      "isclicked": {"$cond": { if: { $eq: [ "$clicked", true ] }, then: 1, else: 0 }}, 
      "isunsubscribe": {"$cond": { if: { $eq: [ "$unsubscribed", true ] }, then: 1, else: 0 }} 

     } 
    }, 

    { "$group" : 
     { "_id" : "$datePartDay", 
      "delivered" : { "$sum" :'$isdelivered' }, 
      "clicked" : { "$sum" :'$isclicked' }, 
      "unsubscribed" : { "$sum" :'$isunsubscribe' } 
     } 
    } 
    ],function (err, result) { 
     if (err) { 
      console.log(err); 
     } else { 
      console.log(result); 
     } 
    }); 

Gesamtergebnis:

[ 
     { 
     "_id": "12-1-2017", 
     "delivered": 0, 
     "clicked": 1, 
     "unsubscribed": 1 
     }, 
     { 
     "_id": "11-1-2017", 
     "delivered": 2, 
     "clicked": 1, 
     "unsubscribed": 0 
     } 
    ] 
  • Ist es möglich, neue Felder hinzufügen, um zu ergeben, dass in der Sammlung nicht etwas wie "Datum" existiert?

  • Ist es möglich, fehlende Datumsfelder mit Dummy-Daten zu ergänzen?

+0

Sie können mit Feldern, die Sie – styopdev

+0

hinzufügen möchten nach $ group neue $ Projizierungsoperation hinzufügen Was Version mongo sind Sie? – Veeram

+0

@SagarReddy, Mongo-Version: 3.2.6 – Kepler

Antwort

3

Die $project Stufen Sie haben redundant ist. Sie können diese ganze Logik ganz einfach auf $group Bühne verschieben und mit $project Bühne abschließen, um Ihre Antwort neu zu formatieren.

Etwas wie das unten.

[{ 
    "$match": { 
     "$and": [{ 
      updatedAt: { 
       $lt: new Date('1-13-2017') 
      } 
     }, { 
      updatedAt: { 
       $gte: new Date('1-05-2017') 
      } 
     }] 
    } 
}, { 
    "$group": { 
     "_id": { 
      $dateToString: { 
       format: "%m-%d-%Y", 
       date: "$updatedAt" 
      } 
     }, 
     "delivered": { 
      $sum: { 
       "$cond": { 
        if: { 
         $eq: ["$delivered", true] 
        }, 
        then: 1, 
        else: 0 
       } 
      } 
     }, 
     "clicked": { 
      $sum: { 
       "$cond": { 
        if: { 
         $eq: ["$clicked", true] 
        }, 
        then: 1, 
        else: 0 
       } 
      } 
     }, 
     "unsubscribed": { 
      $sum: { 
       "$cond": { 
        if: { 
         $eq: ["$unsubscribed", true] 
        }, 
        then: 1, 
        else: 0 
       } 
      } 
     } 
    } 
}, { 
    "$project": { 
     "_id": 0, 
     "date": "$_id", 
     "delivered": 1, 
     "clicked": 1, 
     "unsubscribed": 1 
    } 
}] 
+0

Es hat funktioniert, danke Bruder. Ist es möglich, fehlende Datumsfelder mit Dummy-Daten hinzuzufügen? – Kepler

+0

np Ich glaube nicht, dass das möglich ist oder früher, ich bin mir ohnehin nicht bewusst, das zu tun. tbh es ist sinnvoll, diese Dummy-Datenlogik auf der Client-Seite zu haben. – Veeram

+0

Sie sollten Ihrer Pipeline keine weitere '$ project'-Stufe hinzufügen, wie Sie es getan haben. Es ist redundant und verursacht einen Leistungsabfall in Ihrer Anwendung. – styvane

1

Es ist möglich.

ich Ihnen zeigen, meine Art und Weise, das zu tun:

function (err, res) {    
    if (err) { 
     console.log(err); 
    } else { 
     console.log(res); 
     var result = res.map(function(item) { 
        var jsonValue = {}; 
        jsonValue["_id"] = item._id; 
        jsonValue["delivered"]= item.delivered; 
        jsonValue["clicked"] = item.clicked; 
        // You can add what you want 
        jsonValue["date"] = new Date(); 
        return jsonValue; 
     } 
    }  
} 
+0

Danke, Gibt es eine Option mit Aggregatfunktion? – Kepler

0

arr.map ist gut, aber es gibt einen besseren Weg, um das gleiche Ergebnis über $ addFields zu erreichen, nur Code unten rechts nach

{ $group : 
    { _id : "$datePartDay", 
     delivered : { "$sum" :'$isdelivered' }, 
     clicked : { "$sum" :'$isclicked' }, 
     unsubscribed : { "$sum" :'$isunsubscribe' } 
    } 
} 
{ $addFields: 
    { 
     date: new Date() 
    } 
} 

Bühne $ Gruppe einfügen und Sie erhalten:

[ 
    { 
    "_id": "12-1-2017", 
    "delivered": 0, 
    "clicked": 1, 
    "unsubscribed": 1 
    "date": 2018-02-17T06:12:53.538Z 
    }, 
    { 
    "_id": "11-1-2017", 
    "delivered": 2, 
    "clicked": 1, 
    "unsubscribed": 0 
    "date": 2018-02-17T06:12:53.538Z 
    } 
] 
Verwandte Themen