sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB/Mongoose Hvordan parrer jeg to db-indgange uden konflikter?

I forlængelse af mit oprindelige svar , det er igen noget, hvor en anden tankegang kan komme dig til hjælp. Og som sådan lader det til at handle mere om arkitektur end at sige, at implementering af din kode "på en bestemt måde" vil være den bedste vej at gå.

Ud fra din kommentar til det og dit spørgsmål her, ser det ud til, at problemet du skal løse er, hvordan du justerer antallet af tropper for de andre bruger, der spiller træk. Lad os komme i gang med at se på de samme data igen:

{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }

Foretag "flytningen"

Så situationen her er, at bruger "B" lige har foretaget deres træk og begået 62 enheder i det træk. I det foregående indlæg forklarede jeg, hvordan man får flyttet tilbage for den matchende bruger "A", og derfor kan du "parre" dem og bestemme gevinsten.

Tag det videre, overvej, hvad der skete i anmodningen. Bruger "B" indsendt, så indsætter du dokumentet for deres flytning, så læser du det matchende tilbage. Så lige nu har du begge dokumenter i hukommelsen til anmodningen. Hvis du overvejer sessionsdataene, har du måske noget som dette (på en meget kort måde):

{
    currentUnits: 100
}

Lad os kalde det starttælleren. Så når du indsender et træk fra brugeren, nedsætter du bare antallet af tropper, de har. Så når du laver indsættelsen af 62 tropper, tælleren går til dette:

{
    currentUnits: 38
}

Det er god praksis, da du gør det ved indsættelsesbekræftelsen under flytningen. Men næste gang inden for det tilbagekald, skal du som sagt finde, og det kun returnerer ét dokument. Nu har du de oplysninger, du kan sammenligne og regne. Bruger "B" vinder, så du kan justere din sessionsværdi:

{
    currentUnits: 150
}

Så det burde dække alt for flytningen for bruger "B". Du tog enheder væk, når et træk blev spillet, du matchede den anden spiller, så "gjorde du matematikken" og justerede dine resultater. Færdig! Åh, og du har gemt alle sessionsdataene i en persistent butik gjorde du ikke? Nikke ja. Og også at sessionsdata er bundet til brugerhåndtaget (eller brugeren er faktisk sessions-id'et) for at få adgang til at ændre det.

Det eneste, der er tilbage, er at "underrette" den anden spiller.

Fortælle en anden nyheden

Denne del skal være enkel. Så jeg koder det ikke for dig. Du bruger socket.io for din ansøgning, så alt dette handler om er at sende en besked. Det betyder, at de data du "udsender" fortæller den anden bruger på klienten, at de "mistede deres tropper", uanset hvordan du vil håndtere det. Men husk også, at du "tog væk" disse enheder, når deres flytter blev indsendt. I alle tilfælde er det at sikre, at ingen kan begå mere, end de har.

Den eneste mulige ting at tale om her er skalering din ansøgning ud over én instans. Så du kan tale glad med begivenheder på "node", som alle arbejder på en serverinstans, men for at "skalere" skal du sende beskeder mellem forskellige forekomster.

En måde at håndtere dette på ved hjælp af MongoDB kan være med en begrænsede samlinger .

Bortset fra hvad begrænsede samlinger generelt gør i den måde at holde et sæt størrelse for en samling af dokumenter, er der en ting mere, de tilbyder, og det er en tailable cursor . En ret atypisk måde at oprette en med nodedriveren ville være sådan:

var options = { tailable: true, awaitdata: true, numberOfRetries: -1 };
var cursor = collection.find(query, options).sort({ $natural: 1 });

De fulde muligheder er angivet i Cursor() afsnittet på siden med drivermanualen. Du kan komme til disse "native" metoder i mongoose på den typiske måde.

Hvad en "tailable" cursor er sat op til at gøre, er at "følge" det "sidst indsatte" dokument i samlingen, og du kan sidde og "følge" på denne måde med en jævn afstemning, meget som i:

    (function more() {
        cursor.nextObject(handle(function(doc) {
            if (!doc) return setTimeout(poll, self.wait);

            callback(doc);
            latest = doc._id;
            more();
        }));
    })();

Så inden for en sådan konstruktion "finder" du det nyligt indsatte dokument og videregiver til dit indre tilbagekald de oplysninger, der skal behandles, hvor du "sender" beskeder til klienter, opdaterer ting og hvad du ellers vil gøre.

Tilbage til din egentlige "anmodning", så ville du udstede et indlæg, efter at du "gjorde din matematik" til den separate "capped collection". Du vil have noget meningsfuldt ved kort som:

{ "player": "B", "vsplayer": "A", "win": 50, "loss": 62 }

Og igen er disse bare indsætter. Så du ville oprette et TTL-indeks for at håndtere sletningerne over tid og være begrænset, ville de gamle poster naturligvis drænes ved at blive "skubbet ud" af de poster, der findes i samlingen.

På din "klient"-side holder hver tilsluttet brugerapplikation styr på den "sidste _id"-værdi, der vises. Så de nyligt indsatte poster er altid større i værdi i forhold til de "ældre" tidligere.

Så der er "én måde" at bruge MongoDB til at skabe en vedvarende kø, som du kan behandle sekventielt for at dele meddelelser, der passerer mellem flere applikationsserverinstanser.

Afsluttende ord

Med alt sagt for at implementere en "tail-able" markør på denne måde, ville jeg for mine penge bruge zeromq eller noget lignende. Men du finder måske MongoDB-metoden mere egnet til dig, hvis du ikke ønsker at dykke ned i en anden teknologi. Eller måske er denne form for "skalerbarhed" ikke nødvendig af din applikation (i det mindste på dette stadium), og blot at overføre til "socket.io" metoder inden for anmodningen ville være nok. Op til dig.

I vid udstrækning synes du stadig at være "hængt op" på dine begreber om "skæring" og "sletning". Dette var hensigten at dække i det sidste svar og var at sige, at sletning af dokumenter, når de behandles, er ikke påkrævet . Den beskrevne proces sikrer at du aldrig får "samme par" tilbage på enhver anmodning.

Jeg vil opfordre dig til at "genlæse" den information og virkelig forstår processen. Og spørg hvis du har spørgsmål. Ud fra det, der er blevet diskuteret der, er analogien af ​​dit dataadgangsmønster mere som "at spille af en stak" end "matchende par".

Så hvad du fik som svar, følger videre med logikken beskrevet her er alt du skal bruge for at opsætte dine dataadgangsmønstre. Din anden komponent vil selvfølgelig være beskeden, men dette giver dig adgang til de data, du har brug for.




  1. ZRANGESTORE tidligere Redis 6.2.0

  2. Hvordan opretter man en CUPS-tjeneste til mongoDB?

  3. Beregn gennemsnitsværdien af ​​et mongodb-dokument

  4. Gensample tidsseriedata ved hjælp af Javascript og Mongodb