Spring Data MongoDB: Projections and Aggregations

1. Oversikt

Spring Data MongoDB gir enkle abstraksjoner på høyt nivå til det opprinnelige spørrespråket i MongoDB. I denne artikkelen, vi vil utforske støtten til Framework og Aggregation framework.

Hvis du er ny i dette emnet, se vår innledende artikkel Introduksjon til Spring Data MongoDB.

2. Projeksjon

I MongoDB er projeksjoner en måte å hente bare de nødvendige feltene i et dokument fra en database. Dette reduserer mengden data som må overføres fra databaseserver til klient og øker dermed ytelsen.

Med Spring Data MongDB kan anslag brukes både med MongoTemplate og MongoRepository.

Før vi går videre, la oss se på datamodellen vi skal bruke:

@Document offentlig klasse bruker {@Id privat streng-id; privat strengnavn; privat Hele alder; // standard getters og setters}

2.1. Anslag ved hjelp av MongoTemplate

De inkludere() og utelukke() metoder på Felt klasse brukes til å inkludere og ekskludere henholdsvis felt:

Query query = new Query (); query.fields (). inkluderer ("navn"). ekskluder ("id"); Liste john = mongoTemplate.find (spørring, User.class);

Disse metodene kan lenkes sammen for å inkludere eller ekskludere flere felt. Feltet merket som @Id (_id i databasen) blir alltid hentet med mindre eksplisitt ekskludert.

Ekskluderte felt er null i modellklasseforekomst når poster hentes med projeksjon. I tilfelle felt er av primitiv type eller wrapper-klasse, er verdien av ekskluderte felt standardverdier for de primitive typene.

For eksempel, String ville vært null, int/Heltall ville vært 0 og boolsk/Boolsk ville vært falsk.

Således i eksemplet ovenfor er Navn felt ville være John, id ville vært null og alder ville vært 0.

2.2. Anslag ved hjelp av MongoRepository

Mens du bruker MongoRepositories, er Enger av @Spørsmål merknader kan defineres i JSON-format:

@Query (value = "{}", fields = "{name: 1, _id: 0}") List findNameAndExcludeId ();

Resultatet ville være det samme som å bruke MongoTemplate. De verdi = ”{}” betegner ingen filtre, og dermed blir alle dokumentene hentet.

3. Aggregering

Aggregering i MongoDB ble bygget for å behandle data og returnere kalkulerte resultater. Data behandles trinnvis, og utdataene fra ett trinn leveres som input til neste trinn. Denne evnen til å bruke transformasjoner og gjøre beregninger på data i trinn gjør aggregering til et veldig kraftig verktøy for analyse.

Spring Data MongoDB gir en abstraksjon for innfødte aggregeringsspørsmål ved hjelp av de tre klassene Aggregering som pakker inn et aggregeringsspørsmål, AggregationOperation som omslutter individuelle rørledningsetapper og AggregationResults som er beholderen med resultatet produsert ved aggregering.

For å utføre og aggregering, må du først lage aggregeringsrørledninger ved hjelp av de statiske byggemetodene på Aggregering klasse, og opprett deretter en forekomst av Aggregering bruker newAggregation () metoden på Aggregering klasse og til slutt kjøre aggregeringen ved hjelp av MongoTemplate:

MatchOperation matchStage = Aggregation.match (nye kriterier ("foo"). Er ("bar")); ProjectionOperation projectStage = Aggregation.project ("foo", "bar.baz"); Aggregasjonsaggregering = Aggregation.newAggregation (matchStage, projectStage); AggregationResults output = mongoTemplate.aggregate (aggregation, "foobar", OutType.class);

Vær oppmerksom på at begge MatchOperation og ProjeksjonOperasjon implementere AggregationOperation. Det er lignende implementeringer for andre aggregasjonsrørledninger. OutType er datamodellen for forventet produksjon.

Nå vil vi se på noen få eksempler og forklaringer deres for å dekke de største aggregasjonsrørledninger og operatører.

Datasettet som vi skal bruke i denne artikkelen lister opp detaljer om alle postnummerene i USA som kan lastes ned fra MongoDB repository.

La oss se på et eksempeldokument etter at vi har importert det til en samling som heter glidelåser i test database.

{"_id": "01001", "city": "AGAWAM", "loc": [-72.622739, 42.070206], "pop": 15338, "state": "MA"}

For enkelhets skyld og for å gjøre koden kortfattet, vil vi i de neste kodebitene anta at alle statisk metoder for Aggregering klasse importeres statisk.

3.1. Få alle stater med en befolkning større enn 10 millioner orden etter befolkning synkende

Her vil vi ha tre rørledninger:

  1. $ gruppe scenen oppsummerer befolkningen av alle postnummer
  2. $ match scenen for å filtrere ut stater med befolkning over 10 millioner
  3. $ sort scenen for å sortere alle dokumentene i fallende rekkefølge etter befolkning

Den forventede produksjonen vil ha et felt _id som stat og felt statePop med den totale statlige befolkningen. La oss lage en datamodell for dette og kjøre aggregeringen:

offentlig klasse StatePoulation {@Id privat strengstat; private Heltall statePop; // standard getters og setters}

De @Id merknader vil kartlegge _id felt fra utdata til stat i modellen:

GroupOperation groupByStateAndSumPop = group ("state") .sum ("pop"). As ("statePop"); MatchOperation filterStates = samsvar (nye kriterier ("statePop"). Gt (10000000)); SortOperation sortByPopDesc ​​= sort (Sort.by (Direction.DESC, "statePop")); Aggregeringsaggregering = newAggregation (groupByStateAndSumPop, filterStates, sortByPopDesc); AggregationResults result = mongoTemplate.aggregate (aggregation, "zips", StatePopulation.class);

De AggregationResults klasse redskaper Iterabel og dermed kan vi gjenta det og skrive ut resultatene.

Hvis utdatamodellen ikke er kjent, er standard MongoDB-klassen Dokument kan bli brukt.

3.2. Få den minste staten etter gjennomsnittlig bybefolkning

For dette problemet trenger vi fire trinn:

  1. $ gruppe for å oppsummere den totale befolkningen i hver by
  2. $ gruppe for å beregne gjennomsnittlig befolkning i hver stat
  3. $ sort scene for å ordne stater etter gjennomsnittlig bybefolkning i stigende rekkefølge
  4. $ limit for å få den første staten med lavest gjennomsnittlig bybefolkning

Selv om det ikke nødvendigvis kreves, vil vi bruke et tillegg $ -prosjekt trinn for å formatere dokumentet som per ut Statens befolkning datamodell.

GroupOperation sumTotalCityPop = group ("state", "city") .sum ("pop"). As ("cityPop"); GroupOperation averageStatePop = group ("_ id.state") .avg ("cityPop"). As ("avgCityPop"); SortOperation sortByAvgPopAsc = sort (Sort.by (Direction.ASC, "avgCityPop")); LimitOperation limitToOnlyFirstDoc = limit (1); ProjectionOperation projectToMatchModel = project () .andExpression ("_ id"). As ("state") .andExpression ("avgCityPop"). As ("statePop"); Aggregeringsaggregasjon = newAggregation (sumTotalCityPop, averageStatePop, sortByAvgPopAsc, limitToOnlyFirstDoc, projectToMatchModel); AggregationResults result = mongoTemplate .aggregate (aggregation, "zips", StatePopulation.class); StatePopulation smallestState = result.getUniqueMappedResult ();

I dette eksemplet vet vi allerede at det bare vil være ett dokument i resultatet, siden vi begrenser antall utdatadokumenter til 1 i siste trinn. Som sådan kan vi påberope oss getUniqueMappedResult () for å få det nødvendige Statens befolkning forekomst.

En annen ting å legge merke til er at i stedet for å stole på @Id kommentar til kart _id for å si, har vi eksplisitt gjort det i projeksjonsfasen.

3.3. Få staten med maksimum og minimum postnummer

For dette eksemplet trenger vi tre trinn:

  1. $ gruppe for å telle antall postnummer for hver stat
  2. $ sort å bestille delene etter antall postnummer
  3. $ gruppe for å finne staten med maks og min postnummer ved hjelp av $ først og $ sist operatører
GroupOperation sumZips = group ("state"). Count (). As ("zipCount"); SortOperation sortByCount = sort (Direction.ASC, "zipCount"); GroupOperation groupFirstAndLast = gruppe (). Første ("_ id"). Som ("minZipState"). Første ("zipCount"). Som ("minZipCount"). Siste ("_ id"). Som ("maxZipState"). Siste ("zipCount"). som ("maxZipCount"); Aggregasjonsaggregering = newAggregation (sumZips, sortByCount, groupFirstAndLast); AggregationResults result = mongoTemplate .aggregate (aggregation, "zips", Document.class); Dokumentdokument = resultat.getUniqueMappedResult ();

Her har vi ikke brukt noen modell, men brukt Dokument allerede utstyrt med MongoDB-driver.

4. Konklusjon

I denne artikkelen lærte vi hvordan vi skulle hente spesifiserte felt i et dokument i MongoDB ved hjelp av anslag i Spring Data MongoDB.

Vi lærte også om MongoDB-rammeverkstøtten i Spring Data. Vi dekket store aggregeringsfaser - gruppere, prosjektere, sortere, begrense og matche og så på noen eksempler på praktiske anvendelser. Den komplette kildekoden er tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found