Mongodb: Interogare dimensiunea de matrice imbricate

0

Problema

Am urmatoarea Schema:

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

});

Și aș dori pentru a prelua numai obiectele care au urme cu Apeluri cantitate mai mare decât un număr specificat. Cu alte cuvinte, dimensiunea de cel puțin un imbricate serie de urme ar trebui să fie mai mare decât un număr specificat. Încerc să folosi $elemMatch și $dimensiune, dar fără succes. Pentru acum, am acest cod:

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

În cazul în care minTraceSize este un int.

Ați putea să mă ajutați? Mi-ar aprecia cu adevărat!

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

Cel mai bun răspuns

0

Multumesc pentru datele eșantion. Răspunsul meu va fi un prime MQL soluție, nu o mangustă soluție, astfel încât unele traducerea va fi necesar.

Am fost capabil de a introduce două documente bazate pe comentariile dvs. în post. Am avut de a schimba ObjectId de unul dintre cele două documente eșantion pentru că probele au aceeași valoare a cheii primare și generează o cheie duplicat excepție.

Introduce Date Eșantion

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"
})

Dacă vreau pentru a găsi înregistrările care au mai mult de 0 de elemente din matrice traces Eu pot emite următoarele:

Găsiți mai mult de zero urme

db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })

Acesta returnează următoarele:

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'
  }
]

Găsiți mai mult de 1 urmă

Dacă în loc să vreau să aflu mai multe urme pur și simplu modifica interogarea ușor:

db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })

... și asta se întoarce, cu următoarele rezultate:

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'
  }
]

Concluzie

Când încercarea de a evalua lungimea de matrice în procesorul de interogare trebuie să alegem pentru a utiliza $eval opțiune ca sintaxa pentru MQL nu ia în considerare cazul dumneavoastră de utilizare. La $eval este oarecum de un catch-all opțiune pentru lucruri care nu se potrivesc bine în MQL-cadru.

UPDATE #1 OP introduse cerințe suplimentare. Mai degrabă decât să se uite la numărul de matrice, trebuie să ia în considerare numărul de serie în serie (imbricate interior matrice). Deoarece find() metoda cu $expr nu poate evalua tablouri imbricate trebuie să utilizați în loc de agregare cadru și relaxați-vă exterior matrice. Acest exemplu de magazine forma originală într-un nou câmp numit original apoi inlocuieste radacina după toate de evaluare este completă. De relaxare poate duce la duplicate în conducta vom finaliza cu o $grup pentru a suprima duplicate.

Soluție

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

Bună ziua, vă Mulțumesc pentru răspunsul dumneavoastră rapid! Dar nu este încă destul de o problema... vreau să mă Urme dimensiuni în cel de-al doilea nivel de imbricare. Deci, dacă am avea: { "_id": ObjectId("6175e7ecc62cff004462d4a7"), "urme": [ [ ObjectId("6175e7ecc62cff004462d4a4"), ObjectId("6175e7ecc62cff004462d4a4") ] ], "caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990" }) Acest obiect ar trebui să se întoarcă atunci când am pus 2 la minTraceSize variabilă.
Bruno Medeiros

@BrunoMedeiros - vă rugăm să consultați actualizări în postul meu.
barrypicker

ea a lucrat! Vă mulțumesc atât de mult! =)
Bruno Medeiros

În alte limbi

Această pagină este în alte limbi

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