sql >> Database teknologi >  >> NoSQL >> MongoDB

Tæl særskilte underdokumentfelt og output som navngivne nøgler

Den grundlæggende sag her er at bruge .aggregate() med $unwind fordi du har brug for adgang til værdierne i arrayet som dine grupperingsnøgler og selvfølgelig $group fordi det er sådan man "grupperer" ting:

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

Dette vil give dig output som:

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

Nu burde du virkelig lære at leve med det, for en "liste" i standardmarkørformatet er en god ting, som naturligvis kan gentages. Også IMHO navngivne nøgler egner sig ikke naturligt til datapræsentation, og du vil generelt have en fælles egenskab i en iterabel liste.

Hvis du virkelig er opsat på at bruge det ental navngivne nøgleoutput, så skal du enten bruge MongoDB 3.4.4 eller nyere for at have adgang til $arrayToObject der giver dig mulighed for at bruge værdierne som navne på nøgler, og selvfølgelig $replaceRoot for at bruge det udtryksoutput som det nye dokument, der skal produceres:

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

Eller hvis du ikke har den mulighed, så skal du i stedet konvertere markørens output til kode:

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 }),
  {}
)

Begge flettes sammen til et enkelt objekt med navngivne nøgler fra det originale aggregeringsoutput:

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

Og det viser, at det originale output-resultat virkelig var nok, og at du typisk ønsker, at den slags "endelig omformning" skal udføres i koden, der bruger markøroutputtet, hvis du virkelig overhovedet har brug for den omformning, da den grundlæggende nødvendige data blev returneret alligevel.



  1. Mongodb hvordan indsætter man KUN hvis den ikke eksisterer (ingen opdatering hvis den findes)?

  2. mongodb flere dokumenter indsætte eller opdatere med en unik nøgle

  3. MapReduce i PyMongo

  4. Sådan konfigureres fjederstartwebapp med redis ved hjælp af Docker