Kerangka agregasi sangat ideal untuk itu. Pertimbangkan untuk menjalankan pipeline berikut untuk mendapatkan hasil yang diinginkan.
pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{
"$project": {
"numberOfBooks": {
"$size": {
"$filter": {
"input": "$books",
"as": "el",
"cond": { "$eq": [ "$$el.year", 1990 ] }
}
}
}
}
}
];
db.collection.pipeline(pipeline);
Pipeline di atas menggunakan $filter
operator tersedia untuk MongoDB 3.2 untuk menghasilkan larik yang memenuhi kondisi yang ditentukan yaitu menyaring elemen luar yang tidak memenuhi kriteria. Awal $match
pipeline diperlukan untuk menyaring dokumen yang masuk ke pipeline agregasi lebih awal sebagai strategi pengoptimalan pipeline.
$size
operator yang menerima satu ekspresi sebagai argumen kemudian memberi Anda jumlah elemen dalam larik yang dihasilkan, sehingga Anda memiliki jumlah buku yang diinginkan.
Untuk solusi alternatif yang tidak menggunakan $ filter
operator tidak ditemukan di versi sebelumnya, pertimbangkan operasi pipa berikut:
pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{
"$project": {
"numberOfBooks": {
"$size": {
"$setDifference": [
{
"$map": {
"input": "$books",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.year", 1990 ] },
"$$el",
false
]
}
}
},
[false]
]
}
}
}
}
];
db.collection.pipeline(pipeline);
$project
tahap pipa melibatkan pemasangan susunan buku sehingga Anda menghapus dokumen yang tidak memiliki tahun 1990. Hal ini dimungkinkan melalui $setDifference
dan $map
operator.
$map
operator pada dasarnya menciptakan bidang array baru yang menyimpan nilai sebagai hasil dari logika yang dievaluasi dalam subekspresi untuk setiap elemen array. $setDifference
operator kemudian mengembalikan set dengan elemen yang muncul di set pertama tetapi tidak di set kedua; yaitu melakukan komplemen relatif dari set kedua relatif terhadap yang pertama. Dalam hal ini akan mengembalikan larik buku terakhir yang memiliki elemen dengan tahun 1990 dan selanjutnya $size
menghitung jumlah elemen dalam larik yang dihasilkan, sehingga memberi Anda jumlah buku.
Untuk solusi yang menggunakan $bersantai
operator, ingatlah bahwa (terima kasih atas tanggapan mendalam dari @BlakesSeven di komentar):
dan sebagai upaya terakhir, jalankan pipeline berikut:
pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{ "$unwind": "$books" },
{
"$match": { "books.year": 1990 }
},
{
"$group": {
"_id": null
"count": { "$sum": 1 }
}
}
]
db.collection.pipeline(pipeline)