sql >> Database >  >> NoSQL >> MongoDB

Tel onderscheiden subdocumentveld en uitvoer als benoemde sleutels

Het basisgeval hier is om .aggregate() met $unwind omdat je toegang nodig hebt tot de waarden in de array als je groeperingssleutels en natuurlijk $group omdat je zo dingen "groepeert":

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

Dit geeft je output zoals:

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

Nu moet je daar echt mee leren leven, want een "lijst" in het standaard cursorformaat is een goede zaak die natuurlijk itereerbaar is. Ook IMHO benoemde sleutels lenen zich niet van nature voor gegevenspresentatie en u wilt over het algemeen een gemeenschappelijke eigenschap in een itereerbare lijst.

Als je echt van plan bent om de uitvoer van enkelvoudige benoemde sleutels te gebruiken, dan heb je ofwel MongoDB 3.4.4 of hoger nodig om toegang te krijgen tot $arrayToObject waarmee je de waarden kunt gebruiken als namen van sleutels, en natuurlijk $replaceRoot om die expressie-uitvoer te gebruiken als het nieuwe document om te produceren:

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

Of als je die optie niet hebt, dan zou je in plaats daarvan de cursoruitvoer in code moeten omzetten:

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 worden samengevoegd tot een enkel object met benoemde sleutels uit de oorspronkelijke aggregatie-uitvoer:

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

En dat laat zien dat het oorspronkelijke uitvoerresultaat echt genoeg was, en dat je normaal gesproken wilt dat dat soort "definitieve omvorming" wordt gedaan in de code die de cursoruitvoer gebruikt, als je die omvorming echt nodig hebt sinds de basis benodigde gegevens zijn toch teruggestuurd.



  1. Gebeurtenis op sleutel verloopt

  2. Hoe kan ik machtigingen op veldniveau voor MongoDB implementeren?

  3. MongoDB werkt meerdere records van array bij

  4. Hoe wordt $maxDistance gemeten in MongoDB?