sql >> Databáze >  >> NoSQL >> MongoDB

Počítat odlišné dílčí pole dokumentu a výstup jako pojmenované klíče

Základním případem je použití .aggregate() s $unwind protože potřebujete přístup k hodnotám v poli jako vaše seskupovací klíče a samozřejmě $group protože tak věci „seskupujete“:

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

To vám dá výstup jako:

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

Nyní byste se s tím měli opravdu naučit žít, protože „seznam“ ve výchozím formátu kurzoru je dobrá věc, která je přirozeně iterovatelná. Také IMHO pojmenované klíče se přirozeně nehodí k prezentaci dat a obecně chcete mít společnou vlastnost v iterovatelném seznamu.

Pokud opravdu máte v úmyslu používat výstup singulárních pojmenovaných klíčů, pak budete buď potřebovat MongoDB 3.4.4 nebo vyšší, abyste měli přístup k $arrayToObject které vám umožní použít hodnoty jako názvy klíčů a samozřejmě $replaceRoot za účelem použití tohoto výrazového výstupu jako nového dokumentu k vytvoření:

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

Nebo pokud tuto možnost nemáte, měli byste místo toho konvertovat výstup kurzoru v kódu:

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

Oba se sloučí do jednoho objektu s pojmenovanými klíči z původního výstupu agregace:

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

A to ukazuje, že původní výsledek výstupu byl skutečně dostačující a že obvykle chcete, aby se takový druh „konečné změny tvaru“ provedl v kódu, který používá výstup kurzoru, pokud toto přetvoření vůbec potřebujete od základního potřebná data byla stejně vrácena.



  1. Převeďte pole řetězců na pole ID objektu

  2. StackExchange.Redis s Azure Redis je nepoužitelně pomalý nebo vyvolává chyby vypršení časového limitu

  3. Časová složitost $addToset vs $push, když prvek v poli neexistuje

  4. Mongoose Aggregate :omezení počtu záznamů ve skupině $group