2012-02-23 9 views
19

Utilizzando lo DBREF datatype in MongoDB, un documento può apparire come mostrato di seguito. Ma avere il campo $ref in ogni riga è ridondante poiché ogni riga punta evidentemente alla collezione users.MongoDB - DBREF è necessario?

C'è un modo per fare riferimento ad altri documenti senza avere il campo un po 'ridondante $ref?

{ 
    $id: {$oid : "4f4603820e25f4c515000001"}, 
    title: "User group", 
    users: [ 
     {_id: {$ref: "users", $id: { $oid: "4f44af6a024342300e000002"}}, isAdmin: true } 
    ] 
], 
+4

c'è qualche ragione specifica per cui non si sta utilizzando il semplice collegamento diretto/manuale (è sufficiente inserire l'ObjectId come suggerito di seguito)? –

risposta

31

Dbref a mio parere dovrebbe essere evitato quando si lavora con mongodb, almeno se si lavora con grandi sistemi che richiedono scalabilità.

Poiché so che tutti i driver fanno richiesta aggiuntiva per caricare DBRef, quindi non è "join" all'interno del database, è molto costoso.

Esiste un modo per fare riferimento ad altri documenti senza avere il campo $ ref in qualche modo ridondante $ ?

Sì, mantenere i riferimenti nella mente, creare convenzioni di denominazione per 'chiavi esterne' (qualcosa come RefUserId o semplicemente UserId) e memorizzare solo id del documento di riferimento. Carica i documenti di riferimento autonomamente quando necessario. Inoltre tieni gli occhi aperti per qualsiasi denormalizzazione, incorporando ciò che puoi fare, perché di solito migliora notevolmente le prestazioni.

+3

Non si tratta davvero di un problema con l'utilizzo di un DBRef o solo di _id ma come risolverli con la semantica dei collegamenti. Se si dispone di riferimenti non omogenei (a più raccolte), sarà necessario sia la raccolta che _id == DBRef. –

+1

Giusto per ripetere Scott un po ': se si fa riferimento a oggetti nella stessa collezione, si può semplicemente usare un campo ObjectId –

+0

quindi in futuro l'aggiornamento è più costoso? perché l'aggiornamento non è necessario aggiornare l'intera collezione hmm? –

6

A meno che non si utilizzano i metodi specifici di driver per l'accesso dbref, dovrebbe essere inutile.

Nei casi in cui si gestisce manualmente il join (ovvero si conosce a quale altra raccolta "join"), è sufficiente memorizzare solo l'ObjectId.

2

Dal docs:

Manual references sono un'alternativa, e the docs say riferimenti manuali sono preferibile DBREFs (though I'm not sure why). I DBREF sono utili quando l'oggetto di riferimento risiede in un altro database o dove il nome della raccolta non sarebbe altrimenti evidente.

La denormalizzazione/incorporamento è preferibile a qualsiasi tipo di collegamento perché in tal modo si ottengono aggiornamenti atomici e non è necessario rieseguire la query per i relativi dati.