È necessario utilizzare la pipeline di aggregazione per ottenere un $slice
catena, a causa delle limitazioni nella dichiarazione del progetto che fanno parte della query di ricerca.
La query seguente non è valida perché la prima $slice
restituirebbe un array, invece di un indice, e l'esecuzione del $slice
con ambito esterno fallisce.
db.collection.find({"name":"foo"},{text: {$slice:[{$slice: [1,1]}]}})
Inoltre non c'è modo di lavorare su un campo proiettato nella stessa dichiarazione di progetto, se possibile, avremmo potuto modificare ulteriormente il testo applicandovi una $slice.
La strada da percorrere sarebbe:
Match
il record con il nome come foo.Unwind
l'array di testo per arrivare al primo livello.Unwind
di nuovo per raggiungere il livello che desideriamo.Group
i record insieme per nome.Project
l'ultimo record nel gruppo che è anche l'ultimo elemento dell'ultimo array annidato.
Il codice:
db.collection.aggregate([
{$match:{"name":"foo"}},
{$unwind:"$text"},
{$unwind:"$text"},
{$group:{"_id":"$name","text":{$last:"$text"}}},
{$project:{"name":"$_id","text":1}}
])
o se vuoi proiettare un elemento che appare in un ordine particolare, puoi usare il $skip
e $limit
operazioni per raggiungere questo obiettivo.
var orderOfElement = 2;
db.collection.aggregate([
{$match:{"name":"foo"}},
{$unwind:"$text"},
{$unwind:"$text"},
{$skip:orderOfElement -1},
{$limit:1}
])
Che proietta il secondo elemento in ordine negli array nidificati.