Vraag Modelleren van vriendenvriendschappen in MongoDB


We moeten snel query's kunnen uitvoeren voor de reeks vrienden en vrienden van een gebruiker van vrienden. Dit zou relatief eenvoudig zijn in een relationele database, maar ik ben enigszins vastgelopen op de beste manier om het in MongoDB te bereiken. We slaan de gebruikers-ID's van de vrienden van een gebruiker op in een array in het gebruikersdocument, dus de voor de hand liggende oplossing is om dit te doen:

  • Trek alle gebruikers-ID's van vrienden uit het gebruikersdocument
  • Trek alle vriendenarrays uit gebruikersdocumenten van die vrienden (gebruik een $ in query voor alle vriend-ID's), combineer applicatie-kant in één set en combineer dat met eerste-niveau vriendgebruikers-ID's om een ​​set van alle vrienden en vrienden van vrienden te krijgen
  • Gebruik die set om de laatste query uit te voeren (met $ in) voor alle vrienden en vrienden van vrienden

Hoewel dit eenvoudig lijkt, lijkt dit een enorme hoeveelheid heen en weer, vergeleken met wat we zouden kunnen doen met een join in een relationele database. Is er een efficiëntere manier om dit in MongoDB te doen, of is dit een probleem dat het meest geschikt is voor een RDBMS?


17
2017-09-12 23:43


oorsprong


antwoorden:


Ik heb net diezelfde vraag aan Eliot Horowitz gesteld tijdens de MongoDB SV-conferentie. Hij zei dat de manier waarop hij het zou structureren is om alle gebruikersvrienden op te slaan als ingesloten documenten binnen elke gebruiker. De structuur kan er bijvoorbeeld als volgt uitzien:

{
  _id : ObjectId("4e77bb3b8a3e000000004f7a"),
  username : "alex",
  friends : ["283956723823626626aa", "226567377578888888as", "8738783888aas88a8a88" ]
}

dan kun je een index hebben op user.friends

http://www.mongodb.org/display/DOCS/Indexes#Indexes-IndexingArrayElements

"Wanneer de opgeslagen waarde van een document voor een indexsleutelveld een array is, indexeert MongoDB elk element van de array.Zie de Multikeys-pagina voor meer informatie."

dus om alle vrienden van 'alex' te vinden die ik gewoon kan doen:

db.user.find ({'vrienden': '4e77bb3b8a3e000000004f7a'});


13
2018-01-05 22:01



dit lijkt een enorme hoeveelheid heen en weer, vergeleken met wat we zouden kunnen doen met een join in een relationele database

Dit is allemaal erg relatief. Uw basisaanname bij ophalen "vrienden van vrienden van vrienden" is correct, het is een paar hops en een paar in-memory "onderscheidingen".

Echter vanuit het ruwe perspectief van "totaal werk gedaan", verschilt dit niet heel erg van wat je zou doen met SQL. Ja, het is een relatief eenvoudige SQL-query, maar de server zelf moet nog steeds dezelfde hoeveelheid werk doen, wat netwerkverkeer geven of nemen.

Is er een efficiëntere manier om dit in MongoDB te doen, of is dit een probleem dat het meest geschikt is voor een RDBMS?

Is er een betere manier in MongoDB? Waarschijnlijk niet. Maar het doen van "self-joins" in SQL kan niet gemakkelijk over meerdere servers geschaald worden. In feite gaat het proberen om dit via meerdere servers te doen, in feite over in een soortgelijk proces als het MongoDB-proces.

Technisch gezien is dit een taak die het best wordt gedaan door een Graph Database die noch MongoDB noch een RDBMS is.

Voor Graph-databases kunt u een kijkje nemen Trinity voor .NET of NEO4J.


7
2017-09-13 01:33



Ik geloof dat dit iets is dat beter wordt afgehandeld door een RDBMS (blokdiagram DB's), omdat je duidelijk een "join" -bewerking moet uitvoeren. Hoewel een RDBMS het op dezelfde manier zou kunnen implementeren, zou het de join efficiënter kunnen implementeren en de informatie efficiënter kunnen verspreiden dan MongoDB.

Met dat gezegd, de overhead van het uitvoeren van de "join" query atomisch misschien te duur als je een grote cluster van db-knooppunten en een enorme hoeveelheid gebruikers hebt.

Als u zich geen zorgen maakt over consistentie en atomiciteit van de query en u wilt alleen heen en weer schakelen tussen de toepassing en de DB, kunt u een JavaScript-functie schrijven die de volledige query op MongoDB uitvoert, of gebruik een MapReduce-bewerking voor efficiëntere gedistribueerde query's.


2
2017-09-13 02:19