Mongodb: ricercare la dimensione dell'array nidificati

0

Domanda

Ho il seguente Schema:

Schema({
caller_address: {
    type: String,
    required: true,
},
traces: [[{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Call',
}]]

});

E vorrei recuperare solo gli oggetti che hanno tracce con le Chiamate quantità più grande di un numero specificato. In altre parole, la dimensione di almeno un array nidificato di tracce dovrebbero essere più grande di un numero specificato. Sto cercando di usare $elemMatch e $dimensione, ma senza successo. Per ora, ho questo codice:

CallerTraces.find({ 'traces' : { $elemMatch: { $size : { $gt: minTraceSize } }}})

Dove minTraceSize è un int.

Hai potuto ragazzi help me? Vorrei davvero apprezzare!

arrays mongodb nested
2021-11-23 20:27:28
1

Migliore risposta

0

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" }
        }
    }
])
2021-11-24 21:42:44

Ciao, Grazie per la risposta rapida! Ma non è ancora del tutto il problema... voglio ottenere le Tracce dimensioni nel secondo livello di nidificazione. Quindi, se ho: { "_id": ObjectId("6175e7ecc62cff004462d4a7"), "tracce": [ [ ObjectId("6175e7ecc62cff004462d4a4"), ObjectId("6175e7ecc62cff004462d4a4") ] ], "caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990" }) Questo oggetto dovrebbe tornare quando ho impostato 2 al minTraceSize variabile.
Bruno Medeiros

@BrunoMedeiros - si prega di vedere gli aggiornamenti nel mio post.
barrypicker

ha funzionato! Grazie mille! =)
Bruno Medeiros

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................