Örnek veriler için teşekkürler. Cevabım bir mongoose çözümü değil, ham bir MQL çözümü olacak, bu yüzden bazı çeviri gerekli olacak.
Gönderinizdeki yorumlarınıza dayanarak iki belge ekleyebildim. İki örnek belgeden birinin objectıd'sini değiştirmek zorunda kaldım çünkü örnekleriniz aynı birincil anahtar değerine sahipti ve yinelenen bir anahtar istisnası oluşturuyordu.
Örnek Veri Ekleme
db.CallerTraces.insert(
{
"_id": ObjectId("6175e7ecc62cff004462d4a6"),
"traces": [
[
ObjectId("6175e7ecc62cff004462d4a4")
]
],
"caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})
db.CallerTraces.insert(
{
"_id": ObjectId("6175e7ecc62cff004462d4a7"),
"traces": [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[
ObjectId("6175e7ecc62cff004462d4a4")
]
],
"caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})
Dizide 0'dan fazla öğeye sahip kayıtları bulmak istersem traces
Aşağıdakileri yayınlayabilirim:
Sıfırdan fazla iz bulma
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
Bu, aşağıdakileri döndürür:
Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
[
{
_id: ObjectId("6175e7ecc62cff004462d4a6"),
traces: [ [ ObjectId("6175e7ecc62cff004462d4a4") ] ],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
},
{
_id: ObjectId("6175e7ecc62cff004462d4a7"),
traces: [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[ ObjectId("6175e7ecc62cff004462d4a4") ]
],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
}
]
1'den fazla izleme bul
Bunun yerine birden fazla iz bulmak istersem sorguyu biraz değiştiririm:
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
... ve bu aşağıdaki sonuçlarla geri döner:
Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
[
{
_id: ObjectId("6175e7ecc62cff004462d4a7"),
traces: [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[ ObjectId("6175e7ecc62cff004462d4a4") ]
],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
}
]
Sonuç
Sorgu işlemcisindeki dizinin uzunluğunu değerlendirmeye çalışırken, aşağıdakileri kullanmayı seçmeliyiz: $eval
MQL sözdizimi olarak seçenek kullanım durumunuzu dikkate almaz. Bu $eval
bu, MQL çerçevesine tam olarak uymayan şeyler için bir çeşit yakalama seçeneğidir.
GÜNCELLEME #1
OP ek gereksinimler getirdi. Dizinin sayısına bakmak yerine, dizinin içindeki dizinin sayısını (iç içe geçmiş iç dizi) dikkate almalıyız. $ Expr ile find() yöntemi iç içe geçmiş dizileri değerlendiremediğinden, bunun yerine toplama çerçevesini kullanmalı ve dış diziyi çözmeliyiz. Bu örnek, özgün formu adı verilen yeni bir alanda depolar original
ardından, tüm değerlendirme tamamlandıktan sonra kök yerini alır. Çözülme, boru hattında çoğaltmalara neden olabileceğinden, çoğaltmaları bastırmak için bir $grubuyla sonuçlandırırız.
Çözüm
db.CallerTraces.aggregate([
{
$addFields: {
"original._id": "$_id",
"original.traces": "$traces",
"original.caller_address": "$caller_address"
}
},
{
$unwind: "$traces"
},
{
$match: { $expr: { $gt: [ { $size: "$traces" }, 1 ] } }
},
{
$replaceRoot: { newRoot: "$original" }
},
{
$group:
{
_id: "$_id",
traces: { "$first": "$traces" },
caller_address: { "$first": "$caller_address" }
}
}
])