MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Spring Data MongoDB:Proyeksi dan Agregasi

1. Ikhtisar

Spring Data MongoDB menyediakan abstraksi tingkat tinggi sederhana ke bahasa kueri asli MongoDB. Dalam artikel ini, kita akan mengeksplorasi dukungan untuk kerangka Proyeksi dan Agregasi.

Jika Anda baru mengenal topik ini, lihat artikel pengantar kami Pengantar Data Musim Semi 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 MongDB, proyeksi dapat digunakan baik dengan MongoTemplate dan MongoRepository.

Sebelum kita 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

termasuk() dan kecualikan() metode di Field class digunakan untuk memasukkan dan mengecualikan bidang masing-masing:

Query query = new Query();
query.fields().include("name").exclude("id");
List<User> john = mongoTemplate.find(query, User.class);

Metode ini dapat digabungkan bersama untuk menyertakan atau mengecualikan beberapa bidang. Bidang ditandai sebagai @Id (_id dalam database) selalu diambil kecuali secara eksplisit dikecualikan.

Bidang yang dikecualikan adalah null dalam contoh kelas model ketika catatan diambil dengan proyeksi. Dalam kasus di mana bidang adalah tipe primitif atau kelas pembungkusnya, maka nilai bidang yang dikecualikan adalah nilai default dari tipe primitif.

Misalnya, String akan menjadi null , ke /Bilangan bulat akan menjadi 0 dan boolean /Boolean akan menjadi salah .

Jadi dalam contoh di atas, nama bidangnya adalah John , id akan menjadi null dan usia akan menjadi 0.

2.2. Proyeksi Menggunakan MongoRepository

Saat menggunakan MongoRepositories, bidang dari @Kueri anotasi dapat didefinisikan 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. Agregasi

Agregasi di MongoDB dibangun untuk memproses data dan mengembalikan hasil yang dihitung. Data diproses secara bertahap dan output dari satu tahap diberikan sebagai input ke tahap berikutnya. Kemampuan untuk menerapkan transformasi dan melakukan perhitungan pada data secara bertahap menjadikan agregasi alat yang sangat kuat untuk analitik.

Spring Data MongoDB menyediakan abstraksi untuk kueri agregasi asli menggunakan tiga kelas Agregasi yang membungkus kueri agregasi, AggregationOperation yang membungkus setiap tahapan pipeline dan AggregationResults yang merupakan wadah dari hasil yang dihasilkan oleh agregasi.

Untuk melakukan dan agregasi, pertama-tama, buat pipeline agregasi menggunakan metode static builder di Aggregation kelas, lalu buat instance Agregasi menggunakan newAggregation() metode pada Agregasi class dan akhirnya jalankan agregasi 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 keduanya MatchOperation dan Operasi Proyeksi menerapkan AggregationOperation . Ada implementasi serupa untuk saluran agregasi lainnya. Tipe Luar adalah model data untuk keluaran yang diharapkan.

Sekarang, kita akan melihat beberapa contoh dan penjelasannya untuk mencakup pipeline dan operator agregasi utama.

Kumpulan data yang akan kita gunakan dalam artikel ini mencantumkan rincian 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 dalam pengujian basis data.

{
    "_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 menganggap bahwa semua statis metode Agregasi kelas diimpor secara statis.

3.1. Dapatkan Semua Negara Bagian Dengan Populasi Lebih Dari 10 Juta Pesanan berdasarkan Populasi Menurun

Di sini kita akan memiliki tiga jalur pipa:

  1. $group tahap menjumlahkan populasi semua kode pos
  2. $match panggung untuk menyaring negara bagian dengan populasi lebih dari 10 juta
  3. $sort tahap untuk mengurutkan semua dokumen dalam urutan populasi

Output yang diharapkan akan memiliki bidang _id sebagai negara bagian dan bidang statePop dengan jumlah penduduk 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
}

@Id anotasi akan memetakan _id bidang 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);

AggregationResults kelas mengimplementasikan Iterable dan karenanya kami dapat mengulanginya dan mencetak hasilnya.

Jika model data keluaran tidak diketahui, kelas MongoDB standar Dokumen dapat digunakan.

3.2. Dapatkan Negara Bagian Terkecil berdasarkan Populasi Kota Rata-rata

Untuk masalah ini, kita membutuhkan empat tahap:

  1. $group untuk menjumlahkan total populasi setiap kota
  2. $group untuk menghitung rata-rata populasi setiap negara bagian
  3. $sort tahap untuk mengurutkan negara bagian berdasarkan populasi kota rata-rata mereka dalam urutan menaik
  4. $batas untuk mendapatkan negara bagian pertama dengan rata-rata populasi kota terendah

Meskipun tidak selalu diperlukan, kami akan menggunakan $project tambahan tahap untuk memformat ulang dokumen sesuai StatePopulation model data.

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 telah 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 StatePopulation . yang diperlukan contoh.

Hal lain yang perlu diperhatikan adalah, alih-alih mengandalkan @Id anotasi untuk memetakan _id untuk menyatakan, kami telah melakukannya secara eksplisit dalam tahap proyeksi.

3.3. Dapatkan Status Dengan Kode Pos Maksimum dan Minimum

Untuk contoh ini, kita membutuhkan tiga tahap:

  1. $group untuk menghitung jumlah kode pos untuk setiap negara bagian
  2. $sort untuk memesan negara bagian dengan jumlah kode pos
  3. $group untuk menemukan negara bagian dengan kode pos maks dan min menggunakan $first dan $terakhir operator
GroupOperation sumZips = group("state").count().as("zipCount");
SortOperation sortByCount = sort(Direction.ASC, "zipCount");
GroupOperation groupFirstAndLast = group().first("_id").as("minZipState")
  .first("zipCount").as("minZipCount").last("_id").as("maxZipState")
  .last("zipCount").as("maxZipCount");

Aggregation aggregation = newAggregation(sumZips, sortByCount, groupFirstAndLast);

AggregationResults<Document> result = mongoTemplate
  .aggregate(aggregation, "zips", Document.class);
Document document= result.getUniqueMappedResult();

Di sini kami tidak menggunakan model apa pun tetapi menggunakan Dokumen sudah dilengkapi dengan driver MongoDB.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mekanisme keamanan apa yang dimiliki Meteor?

  2. Impor lebih dari 1 file json menggunakan mongoimport

  3. mongodb TTL tidak menghapus dokumen

  4. Operator Pipa Agregasi MongoDB $gte

  5. MongoDB - bagaimana cara menanyakan item bersarang di dalam koleksi?