2012-11-30 14 views
10

Considerati i seguenti schemi concorrenti con un massimo di 100.000 amici, sono interessato a trovare la soluzione più efficiente per le mie esigenze.Prestazioni del sottocampo mate incorporato vs MongoDB

Doc1 (indice user_id)

{ 
"_id" : "…", 
"user_id" : "1", 
friends : { 
    "2" : { 
     "id" : "2", 
     "mutuals" : 3 
    } 
    "3" : { 
     "id" : "3", 
     "mutuals": "1" 
    } 
    "4" : { 
     "id" : "4", 
     "mutuals": "5" 
    } 
} 
} 

Doc2 (indice composito multi tasto sulla user_id & friends.id)

{ 
"_id" : "…", 
"user_id" : "1", 
friends : [ 
    { 
     "id" : "2", 
     "mutuals" : 3 
    }, 
    { 
     "id" : "3", 
     "mutuals": "1" 
    }, 
    { 
     "id" : "4", 
     "mutuals": "5" 
    } 
]} 

io non riesco a trovare tutte le informazioni sul efficienza del recupero del sottocampo. So che Mongo implementa i dati internamente come BSON, quindi mi chiedo se questo significhi che una proiezione è un O binario (log n)?

In particolare, dato un user_id per scoprire se esiste un amico con friend_id, come sarebbero confrontate le due diverse query su ogni schema? (Supponendo gli indici di cui sopra) Si noti che non importa cosa viene restituito, solo che non viene restituito nulla se l'amico esiste.

Doc1col.find({user_id : "…"}, {"friends.friend_id"}) 
Doc2col.find({user_id : "…", "friends.id" : "friend_id"}, {"_id":1}) 

Anche di interesse è come funziona il modificatore $ set. Per lo schema 1, data la query Doc1col.update({user_id : "…"}, {"$set" : {"friends.friend_id.mutuals" : 5}), come funziona la ricerca su friends.friend_id? Si tratta di un'operazione O (log n) (dove n è il numero di amici)?

Per lo schema 2, in che modo la query Doc2col.update({user_id : "…", "friends.id" : "friend_id"}, {"$set": {"friends.$.mutuals" : 5}) viene confrontata con quella di cui sopra?

+3

Vai con lo stile della matrice (Doc2) poiché le chiavi dinamiche non hanno quasi mai l'approccio giusto. Inoltre, non utilizzare virgolette intelligenti (non è una sintassi legale ed è difficile da leggere). – JohnnyHK

+1

Suppongo che Doc2 utilizzi fino a un paio di byte di spazio aggiuntivo, ma come @JohnnyHK dice che Doc1 non è un buon approccio, fidati del numero di domande da parte di persone che usano Doc1 e poi capire che devono spostarsi su Doc2 per fare qualsiasi cosa con il loro schema ... – Sammaye

+0

Grazie per il consiglio. @Sammaye perché Doc2 consumerà un paio di byte di memoria extra? Ti riferisci all'indice? Tra virgolette intelligenti è stato un errore da copia incolla –

risposta

1

doc1 è preferibile se i propri requisiti primari sono presentare i dati all'interfaccia utente in un pacchetto ben gestibile. la sua semplice per filtrare solo i dati desiderati utilizzando una proiezione {}, {friends.2 : 1}

doc2 è il tuo partner più forte dal vostro caso d'uso non si preoccupa il risultato Si noti che in realtà non importa ciò che è tornato e indicizzazione accelererà il recupero .

in cima a quello doc2 permessi la sintassi molto più pulito

db.doc2.findOne({user_id: 1, friends.id : 2}) 

contro

db.doc1.findOne({ $and : [{ user_id: 1 }, { "friends.2" : {$exists: true} }] }) 

su una nota finale, però, si può creare un sparse index su doc1 (e utilizzare $ esiste), ma la tua possibilità di 100.000 amici - ogni amico ha bisogno di un indice scarso - lo rende assurdo. opposto a un numero ragionevole di voci dicono demografia genere [maschio, femmina], agegroup [0-10,11-16,25-30, ..] o più cose impt [gin, whisky, vodka, ...]