Misalkan Anda memiliki dokumen-dokumen berikut dalam koleksi saya:
{
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
{
"shape":"square",
"color":"blue"
},
{
"shape":"circle",
"color":"red"
}
]
},
{
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
{
"shape":"square",
"color":"black"
},
{
"shape":"circle",
"color":"green"
}
]
}
Lakukan kueri:
db.test.find({"shapes.color": "red"}, {"shapes.color": 1})
Atau
db.test.find({shapes: {"$elemMatch": {color: "red"}}}, {"shapes.color": 1})
Mengembalikan dokumen yang cocok (Dokumen 1) , tetapi selalu dengan SEMUA item array di shapes
:
{ "shapes":
[
{"shape": "square", "color": "blue"},
{"shape": "circle", "color": "red"}
]
}
Namun, saya ingin mendapatkan dokumen (Dokumen 1) hanya dengan larik yang berisi color=red
:
{ "shapes":
[
{"shape": "circle", "color": "red"}
]
}
Bagaimana saya bisa melakukan ini?
aggregate
.db.test.find({}, {shapes: {$elemMatch: {color: "red"}}});
Kerangka Agregasi baru di MongoDB 2.2+ memberikan alternatif untuk Peta / Mengurangi. The
$unwind
operator dapat digunakan untuk memisahkan Andashapes
array menjadi aliran dokumen yang dapat dicocokkan:Hasil dalam:
sumber
$elemMatch
adalah pilihan lain. Saya benar-benar tiba di sini melalui pertanyaan Grup Google di mana $ elemMatch tidak berfungsi karena hanya mengembalikan kecocokan pertama per dokumen.{ $project : { shapes : 1 } }
- yang sepertinya berfungsi dan akan membantu jika dokumen yang dilampirkan besar dan Anda hanya ingin melihat nilaishapes
-nilai kunci.Cara lain yang menarik adalah menggunakan $ redact , yang merupakan salah satu fitur agregasi baru dari MongoDB 2.6 . Jika Anda menggunakan 2.6, Anda tidak perlu $ pelepasan yang dapat menyebabkan masalah kinerja jika Anda memiliki array yang besar.
$redact
"Membatasi konten dokumen berdasarkan informasi yang tersimpan dalam dokumen itu sendiri" . Jadi itu hanya akan berjalan di dalam dokumen . Ini pada dasarnya memindai dokumen Anda dari atas ke bawah, dan memeriksa apakah itu cocok denganif
kondisi Anda yang ada$cond
, jika ada yang cocok itu akan menjaga konten ($$DESCEND
) atau menghapus ($$PRUNE
).Pada contoh di atas, pertama
$match
mengembalikan keseluruhanshapes
array, dan $ redact stripkan ke hasil yang diharapkan.Catatan yang
{$not:"$color"}
diperlukan, karena akan memindai dokumen teratas juga, dan jika$redact
tidak menemukancolor
bidang di tingkat atas ini akan kembalifalse
yang mungkin menghapus seluruh dokumen yang tidak kita inginkan.sumber
$match
sebagai tahap agregat pertama AndaParameter pemilih bidang terbatas pada properti lengkap. Itu tidak dapat digunakan untuk memilih bagian dari array, hanya seluruh array. Saya mencoba menggunakan operator posisional $ , tetapi itu tidak berhasil.
Cara termudah adalah dengan hanya menyaring bentuk di klien .
Jika Anda benar - benar membutuhkan output yang benar langsung dari MongoDB, Anda dapat menggunakan pengurangan peta untuk memfilter bentuk.
sumber
Lebih baik Anda bisa query dalam elemen array yang cocok menggunakan
$slice
itu membantu mengembalikan objek signifikan dalam array.$slice
sangat membantu ketika Anda mengetahui indeks elemen, tetapi kadang-kadang Anda ingin mana elemen array yang cocok dengan kriteria Anda. Anda dapat mengembalikan elemen yang cocok dengan$
operator.sumber
OUTPUT
sumber
Sintaks untuk menemukan di mongodb adalah
dan permintaan kedua yang telah Anda tulis, yaitu
dalam hal ini Anda telah menggunakan
$elemMatch
operator di bagian permintaan, sedangkan jika Anda menggunakan operator ini di bagian proyeksi maka Anda akan mendapatkan hasil yang diinginkan. Anda dapat menuliskan kueri sebagaiIni akan memberi Anda hasil yang diinginkan.
sumber
"shapes.color":"red"
dalam parameter kueri (parameter pertama dari metode find) tidak diperlukan. Anda dapat menggantinya dengan{}
dan mendapatkan hasil yang sama.Terima kasih untuk JohnnyHK .
Di sini saya hanya ingin menambahkan beberapa penggunaan yang lebih kompleks.
sumber
Anda hanya perlu menjalankan kueri
output dari kueri ini adalah
seperti yang Anda harapkan akan memberikan bidang yang tepat dari array yang cocok dengan warna: 'merah'.
sumber
bersama dengan $ project akan lebih tepat elemen pencocokan bijaksana lainnya akan dipukuli bersama dengan elemen lain dalam dokumen.
sumber
Anda juga dapat menemukan beberapa
sumber
$match
untuk mengurangi ruang, kemudian$filter
untuk mempertahankan apa yang Anda inginkan, menimpa bidang input (gunakan output dari$filter
bidangshapes
untuk$project
kembali keshapes
. Catatan gaya: sebaiknya tidak menggunakan nama bidang sebagai yangas
argumen karena dapat menyebabkan kebingungan kemudian dengan$$shape
dan$shape
saya lebih memilih.zz
sebagaias
lapangan karena benar-benar berdiri.sumber
Gunakan fungsi agregasi dan
$project
untuk mendapatkan bidang objek tertentu dalam dokumenhasil:
sumber
Meskipun pertanyaan itu diajukan 9,6 tahun yang lalu, ini telah sangat membantu banyak orang, saya menjadi salah satu dari mereka. Terima kasih semuanya atas semua pertanyaan, petunjuk, dan jawaban Anda. Mengambil dari salah satu jawaban di sini .. Saya menemukan bahwa metode berikut juga dapat digunakan untuk memproyeksikan bidang lain dalam dokumen induk. Ini mungkin bermanfaat bagi seseorang.
Untuk dokumen berikut, kebutuhannya adalah untuk mengetahui apakah seorang karyawan (emp # 7839) memiliki riwayat cuti yang ditetapkan untuk tahun 2020. Riwayat cuti diimplementasikan sebagai dokumen tertanam di dalam dokumen induk Karyawan.
sumber