Kspread: Dotaz veľkosť vnorených polí

0

Otázka

Mám tieto Schémy:

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

});

A ja by som rád, ak chcete prevziať len objekty, ktoré majú stopy s Hovory množstvo väčšie ako zadané číslo. Inými slovami, veľkosť aspoň jeden vnorené pole stopy by mali byť väčšie ako zadané číslo. Snažím sa používať $elemMatch a $veľkosť, ale bez úspechu. Teraz, mám tento kód:

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

Kde minTraceSize je int.

Mohli by ste chlapi mi pomôcť? Ja by som naozaj si to vážim!

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

Najlepšiu odpoveď

0

Vďaka za vzorové údaje. Moja odpoveď bude raw MQL riešenie, nie mongoose riešenie, takže niektoré preklad bude potrebné.

Bol som schopný vložiť dva dokumenty, na základe vašich komentárov v príspevku. Musel som zmeniť ObjectId jedného z dvoch vzorových dokladov, pretože vzorky mali rovnaký primárny kľúč, hodnoty a bol vytvárať duplicitné kľúčové výnimkou.

Vložiť Vzorové Údaje

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

Ak chcem nájsť záznamy, ktoré majú viac ako 0 položiek v poli traces Môžem nasledovný:

Nájsť viac ako nula stopy

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

To vráti nasledovné:

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

Nájsť viac ako 1 stopových

Ak namiesto toho som chcete nájsť viac ako jeden stopových som jednoducho zmeniť dotaz mierne:

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

... a to sa vracia s nasledujúcimi výsledkami:

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

Záver

Pri pokuse o zhodnotenie dĺžka poľa v dotaze procesor musíme zvoliť použitie $eval možnosť, ako syntax pre MQL nepovažuje za váš prípad použitia. Na $eval je trochu catch-all možnosť pre veci, ktoré sa nehodia pekne v MQL rámec.

UPDATE #1 OP zaviedli dodatočné požiadavky. Skôr než sa pozrieť na počet pole, musíme zvážiť počítať z poľa do poľa (vnorené vnútorné pole). Od nájsť() metóda s $expr nemôže vyhodnotiť vnorených polí namiesto toho sa musíme použiť agregácie rámec a odpočinúť si vonkajšie pole. Tento príklad obchody, v pôvodnej forme, v nové pole s názvom original potom nahradí root po všetkých hodnotenie je kompletný. Keďže prejavy môžu mať za následok duplicity v potrubia sme dopracovanie s $skupiny potlačiť duplikáty.

Riešenie

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

Dobrý deň, Ďakujem za vašu rýchlu odpoveď! Ale nie je ešte dosť problém... chcem sa dostať Stopy veľkosti v druhej úrovne vnorenia. Takže, ak som: { "_id": ObjectId("6175e7ecc62cff004462d4a7"), "stopy": [ [ ObjectId("6175e7ecc62cff004462d4a4"), ObjectId("6175e7ecc62cff004462d4a4") ] ], "caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990" }) Tohto objektu by mala vrátiť, keď som sa nastaviť 2 minTraceSize premennej.
Bruno Medeiros

@BrunoMedeiros - prosím pozrite si časť aktualizácie v mojom príspevku.
barrypicker

fungovalo to! Ďakujem moc! =)
Bruno Medeiros

V iných jazykoch

Táto stránka je v iných jazykoch

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