MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Unterdokumentfeld zählen und als benannte Schlüssel ausgeben

Der grundlegende Fall hier ist die Verwendung von .aggregate() mit $unwind weil Sie Zugriff auf die Werte im Array als Ihre Gruppierungsschlüssel benötigen und natürlich $group denn so "gruppiert" man Dinge:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }}
])

Dadurch erhalten Sie eine Ausgabe wie:

{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count":  45 }

Jetzt sollten Sie wirklich lernen, damit zu leben, denn eine "Liste" im Standard-Cursor-Format ist eine gute Sache, die natürlich iterierbar ist. Auch meiner Meinung nach eignen sich benannte Schlüssel nicht von Natur aus für die Datenpräsentation, und Sie möchten im Allgemeinen eine gemeinsame Eigenschaft in einer iterierbaren Liste.

Wenn Sie wirklich beabsichtigen, die Ausgabe der einzelnen benannten Schlüssel zu verwenden, benötigen Sie entweder MongoDB 3.4.4 oder höher, um Zugriff auf $arrayToObject Dadurch können Sie die Werte als Namen von Schlüsseln verwenden, und natürlich $replaceRoot um diese Ausdrucksausgabe als neues zu erzeugendes Dokument zu verwenden:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": null,
    "data": { "$push": { "k": "$_id", "v": "$count" } }
  }},
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": "$data"
    }
  }}
])

Oder wenn Sie diese Option nicht haben, dann sollten Sie stattdessen die Cursorausgabe in Code umwandeln:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }}
]).toArray().reduce((acc,curr) => 
  Object.assign(acc,{ [curr._id]: curr.count }),
  {}
)

Beide verschmelzen zu einem einzigen Objekt mit benannten Schlüsseln aus der ursprünglichen Aggregationsausgabe:

{
    "ANTIQUES": 56,
    "TOOLS": 89,
    "JEWLRY": 45,
    ...
}

Und das zeigt, dass das ursprüngliche Ausgabeergebnis wirklich ausreichend war und dass Sie normalerweise möchten, dass diese Art der "endgültigen Umformung" im Code vorgenommen wird, der die Cursorausgabe verwendet, wenn Sie diese Umformung überhaupt von Grund auf benötigen benötigte Daten wurden trotzdem zurückgegeben.