Kerangka Kerja Agregasi MongoDB - Bekerja Dengan Array
Diterbitkan 22 Juli 2020 Terakhir diperbarui 18 Jan 2021
1. pengantar
Framework Agregasi MongoDB terdiri dari Pipeline, Stages, dan Operator. Ini adalah pipa pemrosesan data, di mana data diproses secara bertahap, setiap tahap melakukan operasi yang berbeda. Operator diterapkan ke data pada setiap tahap untuk perhitungan, transformasi, dan pembentukan keluaran
Kueri agregasi memiliki sintaks
no:
item:
quantity:
price:
6, dan biasanya mengembalikan dokumen sebagai output. Kueri ini digunakan untuk membuat kueri, melaporkan, atau membuat kumpulan perantara yang diubah untuk diproses lebih lanjut. Pada MongoDB v4. 2, pipa juga dapat digunakan untuk memperbarui koleksiKami akan membahas permintaan dan pemutakhiran dengan kode contoh, menggunakan operator untuk bekerja dengan bidang tipe array
Kerangka Agregasi memiliki operator untuk bekerja dengan bidang array dari dokumen koleksi MongoDB. Ada dua kategori operator array
- Operator Ekspresi Array
- Tetapkan Operator Ekspresi
Pada artikel ini, kita akan menggunakan Operator Ekspresi Array menggunakan contoh. Ada sekitar 15 operator dalam kategori ini [pada MongoDB v4. 2], dan kami akan mencoba beberapa di antaranya
2. Data ContohContoh datanya adalah Order dan Order Line Items. Dalam bentuk yang dinormalisasi, kedua entitas ini menghasilkan model dari dua entitas data yang terpisah. Dengan skema fleksibel MongoDB, hubungan One-to-Many ini menghasilkan model sebagai koleksi tunggal. Perhatikan hubungan 1-N ini dengan jelas menentukan bahwa Pesanan dapat memiliki paling banyak 100 item baris maksimum. Data dapat disusun sebagai berikut
orders:
_id:
reference:
date:
status:
customer:
lines: [ 0. 100 ]
_Bidang
no:
item:
quantity:
price:
7 memiliki larik Item Baris Pesanan, dengan setiap baris sebagai sub-dokumen [atau dokumen yang disematkan] dengan atribut berikutno:
item:
quantity:
price:
Bekerja dari
no:
item:
quantity:
price:
8 Shell, kita akan mulai dengan membuat database bernama no:
item:
quantity:
price:
9 dan koleksi bernama > use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
0> use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
_Perintah di atas membuat database dan koleksi dengan satu dokumen. Menanyakan koleksi
> db.orderData.find[].pretty[]
_3. Kueri AgregasiKami akan membuat kode beberapa kueri dengan menerapkan Operator Larik Agregasi pada bidang larik Garis Pesanan dokumen koleksi yang baru dibuat
no:
item:
quantity:
price:
73. 1. Hitung Jumlah Item Baris Untuk Setiap Pesanan
Operator array
> use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
2 mengembalikan panjang arraydb.orderData.aggregate[[
{
$project: { linesSize: { "$size": "$lines" } }
}
]]
Hasil.
_3> use orders > let order = { _id: 1, reference: "ORD-1", date: ISODate[], customer: "Database User", status: "NEW", lines: [ { item: "ABC", quantity: 4, price: 10.5 }, { item: "XYZ", quantity: 1, price: 88.0 }, { item: "123", quantity: 30, price: 1.99 } ] } > db.orderData.insertOne[order]
Dalam agregasi di atas, pipeline hanya memiliki satu tahap, yaitu
> use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
4. > use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
4 memungkinkan penyertaan, pengecualian, dan juga menyertakan bidang turunan baru3. 2. Apakah Bidang Item Baris Bertipe Array?
> use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
6 mengembalikan boolean > use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
7 jika jenis bidang adalah "array"db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
Hasil.
_8> use orders > let order = { _id: 1, reference: "ORD-1", date: ISODate[], customer: "Database User", status: "NEW", lines: [ { item: "ABC", quantity: 4, price: 10.5 }, { item: "XYZ", quantity: 1, price: 88.0 }, { item: "123", quantity: 30, price: 1.99 } ] } > db.orderData.insertOne[order]
3. 3. Menggunakan Dua Operator Array [$size dan $isArray] Bersama-sama
Pertama, kami akan menambahkan dokumen lain ke koleksi
> use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
0; {
"_id" : 2,
"reference" : "ORD-2",
"date" : ISODate["2020-07-13T16:31:26.459Z"],
"customer" : "SQL User",
"status" : "NEW"
}
Permintaan dan output
db.orderData.aggregate[[
{
$project: {
linesSize: {
$cond: [
{ "$isArray": "$lines" },
{ "$size": "$lines" },
0
]
}
}
}
]]
_3> use orders > let order = { _id: 1, reference: "ORD-1", date: ISODate[], customer: "Database User", status: "NEW", lines: [ { item: "ABC", quantity: 4, price: 10.5 }, { item: "XYZ", quantity: 1, price: 88.0 }, { item: "123", quantity: 30, price: 1.99 } ] } > db.orderData.insertOne[order]
_1> db.orderData.find[].pretty[]
Dalam kueri ini, selain operator
> use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
_2 dan > use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
6, kami menggunakan operator bersyarat. > db.orderData.find[].pretty[]
4 digunakan untuk memastikan bidang adalah array dan mendapatkan panjangnya, jika tidak mengembalikan panjang nol. Perhatikan bahwa jika Anda mencoba menggunakan > use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
2 pada bidang yang tidak ada, akan terjadi kesalahan4. Iterasi ArrayIterasi array dan melakukan beberapa operasi seperti pemfilteran, pemetaan, dan pengurangan adalah hal biasa pada elemen array. Anda menggunakan filter untuk mencocokkan dan mempertahankan beberapa nilai saja, dan melakukan pemetaan untuk mengubah setiap elemen array, dan mengurangi untuk menemukan jumlah, rata-rata, dll. , dari elemen larik. Ada operator array untuk melakukan tugas serupa dalam kerangka agregasi.
> db.orderData.find[].pretty[]
6, > db.orderData.find[].pretty[]
7, dan > db.orderData.find[].pretty[]
84. 1. Temukan Item Baris Dengan Harga Lebih Besar Dari N
Operator
> db.orderData.find[].pretty[]
6 memungkinkan iterasi pada elemen array dan menerapkan kondisi yang ditentukan. Hasilnya memiliki elemen array yang sesuai dengan kondisidb.orderData.aggregate[[
{
$match: { lines: { $type: "array" } }
},
{
$addFields: {
lines: {
$filter: {
input: "$lines",
as: "line",
cond: { $gt: [ "$$line.price" , 50.0 ] }
}
}
}
}
]]
Hasil
.. "lines" : [
{
"item" : "XYZ",
"quantity" : 1,
"price" : 88
}
]
Tahap
db.orderData.aggregate[[
{
$project: { linesSize: { "$size": "$lines" } }
}
]]
_0 adalah variasi dari > use orders
> let order =
{
_id: 1,
reference: "ORD-1",
date: ISODate[],
customer: "Database User",
status: "NEW",
lines: [
{ item: "ABC", quantity: 4, price: 10.5 },
{ item: "XYZ", quantity: 1, price: 88.0 },
{ item: "123", quantity: 30, price: 1.99 }
]
}
> db.orderData.insertOne[order]
4, sebagian besar digunakan untuk menambahkan bidang baru yang diubah atau diturunkan ke dokumen. Tahap pertama alur, db.orderData.aggregate[[
{
$project: { linesSize: { "$size": "$lines" } }
}
]]
_2, meneruskan dokumen dengan no:
item:
quantity:
price:
7 sebagai bidang larik ke tahap alur berikutnya4. 2. Hitung Jumlah Total Semua Item Baris
Operator array
> db.orderData.find[].pretty[]
8 memungkinkan iterasi pada elemen array dan melakukan beberapa akumulasi khusus, seperti dalam kasus ini jumlah dari semua jumlah barisno:
item:
quantity:
price:
0Agregasi mengembalikan jumlah semua nilai item baris untuk kedua dokumen sebagai
_5db.orderData.aggregate[[ { $project: { linesSize: { "$size": "$lines" } } } ]]
_6db.orderData.aggregate[[ { $project: { linesSize: { "$size": "$lines" } } } ]]
Operator
db.orderData.aggregate[[
{
$project: { linesSize: { "$size": "$lines" } }
}
]]
_7 digunakan untuk memeriksa apakah suatu bidang tidak ada atau db.orderData.aggregate[[
{
$project: { linesSize: { "$size": "$lines" } }
}
]]
8. Dalam kasus seperti itu, gantikan array kosong. Menggunakan db.orderData.aggregate[[
{
$project: { linesSize: { "$size": "$lines" } }
}
]]
_7, baris pesanan dengan db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
0 diperkenalkan dengan db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
1 [bidang array dengan elemen nol] untuk agregasi ini4. 3. Hitung Bidang Diskon Baru Untuk Setiap Item Baris
Operator array
> db.orderData.find[].pretty[]
7 digunakan untuk mengubah setiap elemen array; . Diskon diberikan sebagai db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
_4 atau db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
5, tergantung pada jumlah baris [db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
6]no:
item:
quantity:
price:
_1Hasil
no:
item:
quantity:
price:
_25. Pembaruan dengan Agregasi PipelineMemulai MongoDB versi 4. 2, Anda dapat menggunakan Pipa Agregasi untuk operasi pembaruan
Fitur ini berguna dalam beberapa situasi, karena pembaruan dapat memerlukan lebih dari satu operasi; . Fitur baru ini memungkinkan semua operasi ini dilakukan secara atomik
Sebagai contoh, hitung pajak untuk setiap item baris pesanan dan perbarui dokumen dengan jumlah pajak. Nilai pajak adalah tiga persen dari nilai item baris untuk pesanan yang memiliki
db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
7 sebagai "BARU"no:
item:
quantity:
price:
_3Permintaan dokumen untuk melihat dokumen yang diperbarui dengan
no:
item:
quantity:
price:
7 menunjukkan bidang db.orderData.aggregate[[
{
$project: { linesIsArray: { "$isArray": "$lines" } }
}
]]
9 baruno:
item:
quantity:
price:
4no:
item:
quantity:
price:
56. Tautan yang Berguna- Referensi Cepat Agregasi Pipeline
- Pipa Agregasi
- Pembaruan dengan Agregasi Pipeline
Kode yang digunakan dalam contoh dapat diakses di GitHub Gist
MongoDBNosqlDatabaseAggregationArray
Laporan
Suka postingan ini?
31
Membagikan
Prasad Saya
Insinyur perangkat lunak berpengalaman dengan keterampilan Java dan basis data
Saya seorang **Java** dan pengembang basis data dengan pengalaman dalam desain, pengembangan, konsultasi, dukungan, dan pemeliharaan. Saya memiliki *sertifikasi* di Java, MongoDB dan OOAD. Pengalaman basis data saya mencakup proyek desain dan pemrograman
Mengikuti
Temukan dan baca lebih banyak posting dari Prasad Saya
memulai
Suka postingan ini?
Tinggalkan suka dan komentar untuk Prasad
31
Kirimkan
Viacheslav Garmash
9 bulan yang lalu
Sampel Anda sangat membantu. Menggunakan $map dan $filter bersamaan dengan hal-hal lain, seperti $mergeObjects membantu saya mengimplementasikan saluran pipa saya tanpa menggunakan tahap $unwind. Terima kasih atas tip yang bagus