Spring Data MongoDB menyediakan abstraksi tingkat tinggi sederhana ke bahasa kueri asli MongoDB. Pada artikel ini, kami akan mengeksplorasi dukungan untuk kerangka kerja Proyeksi dan Agregasi
Jika Anda baru mengenal topik ini, lihat artikel pengantar kami Pengantar Spring Data MongoDB
2. Proyeksi
Di MongoDB, Proyeksi adalah cara untuk mengambil hanya bidang dokumen yang diperlukan dari database. Ini mengurangi jumlah data yang harus ditransfer dari server database ke klien dan karenanya meningkatkan kinerja
Dengan Spring Data MongoDB, proyeksi dapat digunakan dengan MongoTemplate dan MongoRepository
Sebelum melangkah lebih jauh, mari kita lihat model data yang akan kita gunakan
@Document public class User { @Id private String id; private String name; private Integer age; // standard getters and setters }2. 1. Proyeksi Menggunakan MongoTemplate
Metode sertakan() dan kecualikan() pada kelas Bidang digunakan untuk menyertakan dan mengecualikan masing-masing bidang
Query query = new Query(); query.fields().include("name").exclude("id"); List<User> john = mongoTemplate.find(query, User.class);_Metode ini dapat dirangkai bersama untuk menyertakan atau mengecualikan beberapa bidang. Bidang yang ditandai sebagai @Id (_id dalam database) selalu diambil kecuali dikecualikan secara eksplisit
Bidang yang dikecualikan adalah nol dalam contoh kelas model saat rekaman diambil dengan proyeksi. Dalam kasus di mana bidang bertipe primitif atau kelas pembungkusnya, maka nilai bidang yang dikecualikan adalah nilai default dari tipe primitif
Misalnya, String akan menjadi null, int/Integer akan menjadi 0 dan boolean/Boolean akan menjadi false
Jadi dalam contoh di atas, bidang nama adalah John, id adalah nol dan usia adalah 0
2. 2. Proyeksi Menggunakan MongoRepository
Saat menggunakan MongoRepositories, kolom anotasi @Query dapat ditentukan dalam format JSON
@Query(value="{}", fields="{name : 1, _id : 0}") List<User> findNameAndExcludeId();Hasilnya akan sama dengan menggunakan MongoTemplate. Nilai =”{}” menunjukkan tidak ada filter dan karenanya semua dokumen akan diambil
3. Pengumpulan
Agregasi di MongoDB dibangun untuk memproses data dan mengembalikan hasil yang dihitung. Data diproses secara bertahap dan keluaran dari satu tahap disediakan sebagai masukan untuk tahap berikutnya. Kemampuan untuk menerapkan transformasi dan melakukan komputasi pada data secara bertahap menjadikan agregasi alat yang sangat ampuh untuk analitik
Spring Data MongoDB menyediakan abstraksi untuk kueri agregasi asli menggunakan tiga kelas Agregasi yang membungkus kueri agregasi, AggregationOperation yang membungkus tahapan pipa individu dan AggregationResults yang merupakan wadah dari hasil yang dihasilkan oleh agregasi
Untuk melakukan dan agregasi, pertama-tama buat aggregation pipeline menggunakan metode static builder pada kelas Aggregation, lalu buat instance Aggregation menggunakan metode newAggregation() pada kelas Aggregation dan terakhir jalankan aggregation menggunakan MongoTemplate
MatchOperation matchStage = Aggregation.match(new Criteria("foo").is("bar")); ProjectionOperation projectStage = Aggregation.project("foo", "bar.baz"); Aggregation aggregation = Aggregation.newAggregation(matchStage, projectStage); AggregationResults<OutType> output = mongoTemplate.aggregate(aggregation, "foobar", OutType.class);Harap perhatikan bahwa MatchOperation dan ProjectionOperation mengimplementasikan AggregationOperation. Ada implementasi serupa untuk pipa agregasi lainnya. OutType adalah model data untuk output yang diharapkan
Sekarang, kita akan melihat beberapa contoh dan penjelasannya untuk mencakup jalur pipa dan operator agregasi utama
Kumpulan data yang akan kami gunakan dalam artikel ini mencantumkan detail tentang semua kode pos di AS yang dapat diunduh dari repositori MongoDB
Mari kita lihat contoh dokumen setelah mengimpornya ke dalam koleksi yang disebut zips di database pengujian
{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" }_Demi kesederhanaan dan untuk membuat kode ringkas, dalam cuplikan kode berikutnya, kita akan mengasumsikan bahwa semua metode statis kelas Agregasi diimpor secara statis
3. 1. Dapatkan Semua Negara Bagian Dengan Populasi Lebih Besar Dari 10 Juta Diurutkan berdasarkan Menurunnya Populasi
Di sini kita akan memiliki tiga saluran pipa
- Tahap $group menjumlahkan populasi semua kode pos
- Tahap $match untuk menyaring negara bagian dengan populasi lebih dari 10 juta
- $sort tahap untuk mengurutkan semua dokumen dalam urutan populasi
Output yang diharapkan akan memiliki bidang _id sebagai negara bagian dan bidang statePop dengan total populasi negara bagian. Mari buat model data untuk ini dan jalankan agregasi
public class StatePoulation { @Id private String state; private Integer statePop; // standard getters and setters }Anotasi @Id akan memetakan kolom _id dari output ke status dalam model
GroupOperation groupByStateAndSumPop = group("state") .sum("pop").as("statePop"); MatchOperation filterStates = match(new Criteria("statePop").gt(10000000)); SortOperation sortByPopDesc = sort(Sort.by(Direction.DESC, "statePop")); Aggregation aggregation = newAggregation( groupByStateAndSumPop, filterStates, sortByPopDesc); AggregationResults<StatePopulation> result = mongoTemplate.aggregate( aggregation, "zips", StatePopulation.class);_Kelas AggregationResults mengimplementasikan Iterable dan karenanya kita dapat mengulanginya dan mencetak hasilnya
Jika model data keluaran tidak diketahui, Dokumen kelas MongoDB standar dapat digunakan
3. 2. Dapatkan Negara Bagian Terkecil menurut Rata-Rata Populasi Kota
Untuk masalah ini, kita membutuhkan empat tahap
- $group untuk menjumlahkan total populasi setiap kota
- $group untuk menghitung populasi rata-rata dari setiap negara bagian
- tahap $sort untuk mengurutkan negara bagian berdasarkan populasi kota rata-rata dalam urutan menaik
- $limit untuk mendapatkan negara bagian pertama dengan populasi kota rata-rata terendah
Meskipun belum tentu diperlukan, kami akan menggunakan tahapan $project tambahan untuk memformat ulang dokumen sesuai model data StatePopulation
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"); Aggregation aggregation = newAggregation( sumTotalCityPop, averageStatePop, sortByAvgPopAsc, limitToOnlyFirstDoc, projectToMatchModel); AggregationResults<StatePopulation> result = mongoTemplate .aggregate(aggregation, "zips", StatePopulation.class); StatePopulation smallestState = result.getUniqueMappedResult();Dalam contoh ini, kita sudah mengetahui bahwa hanya akan ada satu dokumen dalam hasil karena kita membatasi jumlah dokumen keluaran menjadi 1 pada tahap terakhir. Dengan demikian, kita dapat memanggil getUniqueMappedResult() untuk mendapatkan instance StatePopulation yang diperlukan
Hal lain yang perlu diperhatikan adalah, alih-alih mengandalkan anotasi @Id untuk memetakan _id untuk menyatakan, kami telah melakukannya secara eksplisit dalam tahap proyeksi
3. 3. Dapatkan Negara Dengan Kode Pos Maksimum dan Minimum
Untuk contoh ini, kita membutuhkan tiga tahap
- $group untuk menghitung jumlah kode pos untuk setiap negara bagian
- $sort untuk mengurutkan negara bagian berdasarkan jumlah kode pos
- $group untuk menemukan negara bagian dengan kode pos maks dan min menggunakan operator $first dan $last
Di sini kami tidak menggunakan model apa pun tetapi menggunakan Dokumen yang sudah disediakan dengan driver MongoDB
4. Kesimpulan
Pada artikel ini, kami belajar cara mengambil bidang tertentu dari dokumen di MongoDB menggunakan proyeksi di Spring Data MongoDB
Kami juga belajar tentang dukungan kerangka agregasi MongoDB di Spring Data. Kami membahas fase agregasi utama – grup, proyek, urutkan, batasi, dan cocokkan dan lihat beberapa contoh aplikasi praktisnya. Kode sumber lengkap tersedia di GitHub