Díky za vzorek údajů. Moje odpověď bude syrové MQL řešení, ne mongoose řešení, takže nějaký překlad bude zapotřebí.
Byl jsem schopen chcete-li vložit dva dokumenty založené na vaše komentáře v příspěvku. Musel jsem změnit ObjectId jednoho z dva ukázkové dokumenty, protože vzorky měly stejnou hodnotu primárního klíče a generování duplicitní klíč výjimkou.
Vložit Ukázková Data
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"
})
Pokud chci najít záznamy, které mají více než 0 položek v poli traces
Mohu vydat následující:
Najít více než žádné stopy
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
Tento příkaz vrátí následující:
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'
}
]
Najít více než 1 stopa
Pokud místo toho jsem chtěl najít více než jednu stopu jsem jednoduše změnit dotaz, mírně:
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
... a tato se vrátí s následujícími výsledky:
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ávěr
Při pokusu vyhodnotit délku pole v dotazu procesor musíme volit používat $eval
možnost jako syntaxe pro MQL nepovažuje váš případ použití. Na $eval
je poněkud catch-all volbou pro věci, které se nevejdou pěkně v MQL rámce.
UPDATE #1
OP zavedeny dodatečné požadavky. Spíše než se podívat na počet pole, musíme vzít v úvahu, hrabě z pole do pole (vnořené vnitřní pole). Od find() metoda s $expr nelze hodnotit vnořených polí místo toho musíme použít agregační framework a odpočinout vnější pole. Tento příklad uloží původní podobě v nové pole s názvem original
pak nahradí kořen po všech hodnocení je kompletní. Od odvíjení může v důsledku duplicity v potrubí doladíme s $group k potlačení duplicity.
Řešení
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" }
}
}
])