MongoDB generalmente non è adatto per la modellazione di relazioni grafiche. Esistono database di grafici specializzati che eccellono in questo compito.
Tuttavia, quando non vuoi aggiungere un'altra tecnologia di database al mix, ti consiglio di creare una nuova collezione frienships
e modella ogni relazione di amicizia come un documento con una matrice di due voci, ciascuna di esse un oggetto con le informazioni abbreviate su uno degli utenti di cui hai bisogno per visualizzare una voce nelle tue liste di amici:
{
friendship: [
{
id:123,
name: "Bob",
avatar: "Bob.jpg"
},
{
id:456,
name: "Alice",
avatar: "Alice.jpg"
}
]
}
Il motivo per duplicare le informazioni dai documenti dell'utente nei documenti dell'amicizia è evitare una seconda query alla raccolta degli utenti per ottenere tutti i dati per la visualizzazione di un elenco di amici degli utenti. MongoDB non può fare JOIN può eseguire JOIN solo su raccolte non ripartite
, quindi dovresti evitare di diffondere i dati necessari per un caso d'uso specifico su più raccolte, anche quando ciò significa creare ridondanze. In caso contrario, dovresti eseguire più query una dopo l'altra, il che rallenta notevolmente i tempi di risposta della tua applicazione.
Quando vuoi ottenere la lista amici dell'utente 123, devi eseguire un db.friendships.find({"friendship.id", 123})
(un indice su friendship.id
migliorerà le prestazioni) e quindi riceverà un elenco di documenti in cui Bob è il primo o il secondo amico.
Dovresti quindi iterare questi documenti e produrre le informazioni brevi della voce dell'array che non utente 123.
In alternativa, puoi filtrare le voci Bob sul database con una pipeline di aggregazione. Usa la query $match sopra, $svolgi l'array dell'amicizia e poi $match quei documenti in cui l'id non è 123. Questo sarebbe un compromesso:risparmi la larghezza di banda a spese del carico della CPU sul server del database.
Per chiedere se esiste già una relazione di amicizia, usa:
db.friendships.find( { $and: [
{ "friendship.id": 123 },
{ "friendship.id": 456 }
] } ).count();