2015-06-08 16 views
9

Ecco un esempio da MongoDB tutorial (qui collezione ZIP Code db:MongoDB - oggetti? Perché ho bisogno di _ID complessivamente

db.zipcodes.aggregate([ 
    { $group: { _id: "$state", totalPop: { $sum: "$pop" } } }, 
    { $match: { totalPop: { $gte: 10*1000*1000 } } } 
]) 

se sostituisco _id con qualcos'altro come parola Test, mi metterò messaggio di errore:

"errmsg" : "exception: the group aggregate field 'Test' must be defined as an expression inside an object", 
"code" : 15951, 
"ok" : 0 

qualcuno potrebbe aiutarmi a capire il motivo per cui ho bisogno di _id nel mio comando? ho pensato MongoDB assegna automaticamente gli ID, se usato non fornisce essa.

risposta

5

In uno stage $group, _id viene utilizzato per indicare la condizione del gruppo. Ovviamente ne hai bisogno.

Se si ha familiarità con il mondo SQL, considerarlo come la clausola GROUP BY.


Si prega di notare, in tale contesto anche _id è davvero un identificatore unico nella collezione generato, come per definizione $group non può produrre due documenti aventi lo stesso valore per il campo.

+0

In SQL ho GROUP BY e devo campo per gruppo di $ Stato, _id non assomiglia a nessun analogico SQL. – user1700890

3

Il campo _id è obbligatorio, ma è possibile impostare a null se si fa non desiderio di aggregare rispetto ad una chiave, o le chiavi. Non utilizzarlo risulterebbe in un singolo valore di aggregazione sui campi. In questo contesto agisce quindi una "parola riservata", indicando quale sia la chiave/identificatore "risultante per ciascun gruppo.

Nel suo caso, il raggruppamento per _id: "$state" comporterebbe n risultati aggregati della totalPop, forniti ci sono n valori distinti per state (simile a SELECT SUM() FROM table GROUP BY state). Considerando che,

$group : {_id : null, totalPop: { $sum: "$pop" }}} 

fornirebbe un unico risultato per totalPop (simile a SELECT SUM() FROM table).

Questo comportamento è ben descritto nell'operatore di gruppo documentation.

5

andremo a capire il campo _id all'interno del $group fase & sguardo ad alcune best practice per la costruzione di _id s in fase di aggregazione di gruppo. Diamo un'occhiata a questa domanda:


db.companies.aggregate([{ 
    $match: { 
    founded_year: { 
     $gte: 2010 
    } 
    } 
}, { 
    $group: { 
    _id: { 
     founded_year: "$founded_year" 
    }, 
    companies: { 
     $push: "$name" 
    } 
    } 
}, { 
    $sort: { 
    "_id.founded_year": 1 
    } 
}]).pretty() 

MongoDB $group with document approach

Una cosa che potrebbe non essere chiaro a noi è il motivo per il campo _id è costruito in questo modo "documento"? Abbiamo potuto fare in questo modo, così:


db.companies.aggregate([{ 
    $match: { 
    founded_year: { 
     $gte: 2010 
    } 
    } 
}, { 
    $group: { 
    _id: "$founded_year", 
    companies: { 
     $push: "$name" 
    } 
    } 
}, { 
    $sort: { 
    "_id": 1 
    } 
}]).pretty()

MongoDB $group without document approach

Non lo facciamo in questo modo, perché in questi documenti di output - non è esplicito ciò che significa esattamente questo numero. Quindi, in realtà non lo sappiamo. E in alcuni casi, ciò significa che forse c'è confusione nell'interpretazione di questi documenti.Quindi, un altro caso forse al gruppo un documento _id con più campi:


db.companies.aggregate([{ 
    $match: { 
    founded_year: { 
     $gte: 2010 
    } 
    } 
}, { 
    $group: { 
    _id: { 
     founded_year: "$founded_year", 
     category_code: "$category_code" 
    }, 
    companies: { 
     $push: "$name" 
    } 
    } 
}, { 
    $sort: { 
    "_id.founded_year": 1 
    } 
}]).pretty() 

group an _id document with multiple fields in MongoDB

$push spinge semplicemente gli elementi di matrici di generazione. Spesso, potrebbe essere richiesto di gruppo su campi promossi a livello superiore:


db.companies.aggregate([{ 
    $group: { 
    _id: { 
     ipo_year: "$ipo.pub_year" 
    }, 
    companies: { 
     $push: "$name" 
    } 
    } 
}, { 
    $sort: { 
    "_id.ipo_year": 1 
    } 
}]).pretty()

group on promoted fields to upper level in MongoDB

E 'anche perfetto per avere un'espressione che si risolve in un documento come una chiave _id.

db.companies.aggregate([{ 
    $match: { 
    "relationships.person": { 
     $ne: null 
    } 
    } 
}, { 
    $project: { 
    relationships: 1, 
    _id: 0 
    } 
}, { 
    $unwind: "$relationships" 
}, { 
    $group: { 
    _id: "$relationships.person", 
    count: { 
     $sum: 1 
    } 
    } 
}, { 
    $sort: { 
    count: -1 
    } 
}])

It's also perfect to have an expression that resolves to a document as a _id key in MongoDB

Problemi correlati