2016-04-01 7 views
-2

Wie findet man die Summe des Gesamtwertes aus dem inneren Array?

{ 
 
    "_id" : ObjectId("56fb04fd2e6bb8bc059287c9"), 
 
    "BillNo" : "Bill_001", 
 
    "DateP" : "12-12-2015", 
 
    "Type" : "Cash", 
 
    "Items" : [ 
 
     { 
 
      "id" : NumberInt(1), 
 
      "ItemName" : "cement", 
 
      "Qty" : "100", 
 
      "Rate" : "10", 
 
      "Total" : "1000" 
 
     }, 
 
     { 
 
      "id" : NumberInt(2), 
 
      "ItemName" : "steel", 
 
      "Qty" : "10", 
 
      "Rate" : "50", 
 
      "Total" : "500" 
 
     }, 
 
     { 
 
      "id" : NumberInt(3), 
 
      "ItemName" : "sand", 
 
      "Qty" : "1", 
 
      "Rate" : "1500", 
 
      "Total" : "1500" 
 
     } 
 
    ] 
 
} 
 
{ 
 
    "_id" : ObjectId("56fb05382e6bb8bc059287ca"), 
 
    "BillNo" : "Bill_002", 
 
    "DateP" : "12-10-2015", 
 
    "Type" : "Cash", 
 
    "Items" : [ 
 
     { 
 
      "id" : NumberInt(1), 
 
      "ItemName" : "Paint", 
 
      "Qty" : "50", 
 
      "Rate" : "100", 
 
      "Total" : "5000" 
 
     }, 
 
     { 
 
      "id" : NumberInt(2), 
 
      "ItemName" : "Brush", 
 
      "Qty" : "5", 
 
      "Rate" : "10", 
 
      "Total" : "50" 
 
     } 
 
    ] 
 
}

In der obigen Sammlung speichert die alle Einzelheiten zum Kauf in Hauptdokument und sein Posten Details als innere Anordnung von Haupt Speicherung benötigen ist Einzelteil das Ergebnis wie nachfolgend mit mongodb zu erhalten; Wie finde ich die Summe aus dem inneren Array in mongodb?

Bill_001  1500 
Bill_002  5050 
+1

Alle Ihre Werte von Strings. Sie sollten sie beheben, da Sie nicht wirklich Strings hinzufügen können. –

+0

Ergebnis wird sein wie Bill_001 -> 3000, Bill_002 -> 5050 – Pradeep

+0

Wenn es zu int geändert wird dann wie wird die Mongo Shell? – Pradeep

Antwort

1

Ideal in MongoDB können Sie $map mit $sum als beide einen $group Speicher nutzen und neue Rolle ist, die Mitglieder der bereitgestellten Array in das Hinzufügen:

db.collection.aggregate({ 
    { "$group": { 
     "_id": "$BillNo", 
     "Total": { 
      "$sum": { 
       "$sum": { 
        "$map": { 
        "input": "$Items", 
        "as": "item", 
        "in": "$$item.Total" 
        } 
       } 
      } 
     } 
    }} 
}) 

Oder nur pro Dokument:

db.collection.aggregate({ 
    { "$group": { 
     "_id": "$_id", 
     "BillNo": { "$first": "$BillNo" }, 
     "DateP": { "$first" "$DateP" }, 
     "Type": { "$first": "$Type" } 
     "Total": { 
      "$sum": { 
       "$sum": { 
        "$map": { 
        "input": "$Items", 
        "as": "item", 
        "in": "$$item.Total" 
        } 
       } 
      } 
     } 
    }} 
}) 

Verwendung des anderen Akkumulators $first. Natürlich könnte man wirklich nur $project Mit MongoDB 3.2:

db.collection.aggregate({ 
    { "$project": { 
     "BillNo": 1, 
     "DateP": 1, 
     "Type": 1, 
     "Total": { 
      "$sum": { 
       "$map": { 
       "input": "$Items", 
       "as": "item", 
       "in": "$$item.Total" 
       } 
      } 
     } 
    }} 
}) 

In älteren Versionen müssen Sie noch $unwind auf dem Array zuerst:

db.collection.aggregate([ 
    { "$unwind": "$Items" }, 
    { "$group": { 
     "_id": "$BillNo", 
     "Total": { 
      "$sum": "$Items.Total" 
     } 
    }} 
]) 

Oder wenn Sie pro Dokument hinzugefügt werden:

db.collection.aggregate([ 
    { "$unwind": "$Items" }, 
    { "$group": { 
     "_id": "_id", 
     "BillNo": { "$first": "$BillNo" }, 
     "DateP": { "$first": "$DateP" }, 
     "Type": { "$first": "$Type" }, 
     "Total": { 
      "$sum": "$Items.Total" 
     } 
    }} 
]) 

Aber natürlich nur, wenn Sie die Strings tatsächlich auf numerische Werte fixieren.

Idealerweise kann man es wie dieses Problem zu beheben:

var ops = []; 

db.collection.find().forEach(function(doc) { 
    doc.Items.forEach(function(item) { 
     ops.push({ 
      "updateOne": { 
       "filter": { "_id": doc._id, "Items.id": item.id }, 
       "update": { 
        "$set": { 
         "Items.$.Qty": parseInt(item.Qty), 
         "Items.$.Rate": parseInt(item.Rate), 
         "Items.$Total": parseInt(item.Total) 
        } 
       } 
      }   
     }); 

     // Send batch of updates 
     if (ops.length == 1000) { 
      db.collection.bulkWrite(ops); 
      ops = []; 
     } 
    }) 
}); 

// Clear any unprocessed updates 
if (ops.length > 0) { 
    db.collection.bulkWrite(ops); 
} 
+0

Vielen Dank .. richtig arbeiten. Für den Fall, dass ich BillNo, Date, Type etc ... zusammen mit "Total" anzeigen lassen möchte, wie es sein wird. Ich benutze $ unwind-Methode. Bitte antworten Sie dies auch – Pradeep

+0

@ Pradeep Das ist nicht, was Ihre Frage fragt. Willkommen bei stackoverflow, Sie können hier jeweils eine Frage stellen, und wenn Sie eine andere Frage haben, dann [Stellen Sie eine andere Frage] (http://stackoverflow.com/questions/ask). Sie möchten den Wert von "BillNo" anhäufen, das bedeutet, dass Werte wie "Type" sich natürlich pro Dokument ändern und nicht Teil der Gruppierung sind. Sie können andere [Akkumulatoren] (https://docs.mongodb.org/manual/reference/operator/aggregation-group/) verwenden, aber das ist nicht Teil Ihrer Frage. –

Verwandte Themen