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

Souhrnný počet členů pole odpovídající podmínkám

Chyba je, protože to již není pole poté, co $unwind a proto již není platným argumentem pro $size .

Zdá se, že se pokoušíte „sloučit“ několik existujících odpovědí, aniž byste pochopili, co dělají. Zde opravdu chcete $filter a $size

db.collection.aggregate([
  { "$project": {
    "total": {
      "$size": {
        "$filter": {
          "input": "$Array",
          "cond": { "$eq": [ "$$this.field1", "a" ] }
        }
      }
    }
  }}
])

Nebo „znovu vynalézt kolo“ pomocí $reduce :

db.collection.aggregate([
  { "$project": {
    "total": {
      "$reduce": {
        "input": "$Array",
        "initialValue": 0,
        "in": {
          "$sum": [
            "$$value", 
            { "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
        }
      }
    }
  }}
])

Nebo za to, co jste se snažili udělat s $unwind , ve skutečnosti jste $group znovu, abychom „spočítali“, kolik shod bylo:

db.collection.aggregate([
  { "$unwind": "$Array" },
  { "$match": { "Array.field1": "a" } },
  { "$group": {
    "_id": "$_id",
    "total": { "$sum": 1 }
  }}
])

První dvě formy jsou „optimální“ pro moderní prostředí MongoDB. Konečná podoba s $unwind a $group je "starší" konstrukce, která skutečně nebyla pro tento typ operací nutná od MongoDB 2.6, i když s některými mírně odlišnými operátory.

V těchto prvních dvou v podstatě porovnáváme pole1 hodnotu každého prvku pole, i když je to stále pole. Oba $filter a $reduce jsou moderní operátory navržené pro práci s existujícím polem na místě. Stejné srovnání se provádí na každém z nich pomocí agregace $eq operátor, který vrací booleovskou hodnotu založenou na tom, zda jsou zadané argumenty "rovné" nebo ne. V tomto případě na každý člen pole na očekávanou hodnotu "a" .

V případě $filter , pole ve skutečnosti zůstává nedotčené kromě prvků, které nesplňují zadanou podmínku v "cond" jsou odstraněny z pole. Protože stále máme "pole" jako výstup, můžeme pak použít $velikost operátor k měření počtu prvků pole, které zbyly po zpracování podmínky filtru.

$reduce na druhé straně pracuje přes prvky pole a poskytuje výraz nad každým prvkem a uloženou hodnotu "accumulator", kterou jsme inicializovali pomocí "initialValue" . V tomto případě stejný $eq test se používá v rámci $cond operátor. Toto je "ternární" nebo if/then/else podmíněný operátor, který umožňuje, aby testovaný výraz, který vrací booleovskou hodnotu, vrátil then hodnota, když pravda nebo else hodnota, když false .

V tomto výrazu vrátíme 1 nebo 0 a poskytnout celkový výsledek sečtení této vrácené hodnoty a aktuálního "akumulátoru" "$$value" s $sum operátora, abyste je sečetli.

Konečný formulář byl použit $unwind na poli. To, co to ve skutečnosti dělá, je dekonstrukce členů pole, aby se vytvořil „nový dokument“ pro každého člena pole a s ním související nadřazená pole v původním dokumentu. To efektivně "zkopíruje" hlavní dokument pro každý člen pole.

Jakmile $unwind struktura dokumentů je změněna na „plošší“ formu. To je důvod, proč pak můžete provést následující $match fáze potrubí k odstranění neshodných dokumentů.

Tím se dostáváme k $group který se používá k „sloučení“ všech informací souvisejících se společným klíčem. V tomto případě je to _id pole původního dokumentu, které bylo samozřejmě zkopírováno do každého dokumentu vytvořeného $unwind . Když se vrátíme k tomuto „společnému klíči“ jako jedinému dokumentu, můžeme „spočítat“ zbývající „dokumenty“ extrahované z pole pomocí $sum akumulátor.

Pokud bychom chtěli zbývající „pole“ zpět, můžete $push a znovu sestavte pole pouze se zbývajícími členy:

  { "$group": {
    "_id": "$_id",
    "Array": { "$push": "$Array" },
    "total": { "$sum": 1 }
  }}

Ale samozřejmě namísto použití $size v další fázi procesu můžeme jednoduše stále „počítat“, jako jsme to již udělali s $sum




  1. Typované transakce Redis

  2. Řazení podle relevance pomocí MongoDB

  3. Připojte se a dotazujte se na databázi Mongo přes SSH se soukromým klíčem v Pythonu

  4. Generování _id vs. automatické generování ObjectId v MongoDB