Grazie per i dati di esempio. La mia risposta sarà un raw MQX soluzione, non una mangusta soluzione, in modo che la traduzione sarà richiesto.
Sono stato in grado di inserire due documenti basati su i vostri commenti nel post. Ho dovuto cambiare il ObjectId di uno dei due documenti di esempio, perché i vostri campioni avuto lo stesso valore di chiave primaria ed è stata la generazione di una chiave duplicata eccezione.
Inserire I Dati Di Esempio
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"
})
Se voglio trovare i record che hanno più di 0 elementi nell'array traces
Posso emettere il seguente:
Trovare più di zero tracce
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
Questo restituisce il seguente:
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'
}
]
Trovare più di 1 traccia
Se invece voglio trovare più di una traccia sufficiente modificare la query leggermente:
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
... e questo torna con i seguenti risultati:
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'
}
]
Conclusione
Quando si tenta di valutare la lunghezza dell'array entro il processore di query dobbiamo eleggere i $eval
opzione, come la sintassi per MQL non prendere in considerazione il vostro caso d'uso. Il $eval
è un po ' un catch-all opzione per le cose che non si adatta bene in MQL quadro.
AGGIORNAMENTO #1
OP introdotto ulteriori requisiti. Piuttosto che guardare il conteggio della matrice, si deve considerare il numero di array all'interno della matrice (nested interno dell'array). Dal momento che il metodo find() con il $expr in grado di valutare matrici nidificate dobbiamo invece utilizzare l'aggregazione quadro e rilassarsi esterno array. Questo esempio memorizza la forma originale in un nuovo campo chiamato original
quindi sostituisce la radice dopo tutto la valutazione è completa. Poiché la liquidazione può causare duplicati in cantiere ci finalizzare con un $gruppo di sopprimere i duplicati.
Soluzione
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" }
}
}
])