Det finns faktiskt en "gotcha" listad i dokumentationen för $type
specifikt om arrayer:
När den tillämpas på arrayer matchar $type alla inre element som är av den angivna typen. Utan projektion betyder detta att hela arrayen matchar om något element har rätt typ. Med projektion kommer resultaten att inkludera bara de element av den efterfrågade typen.
Så det betyder att snarare än att upptäcka om "elementet i sig" är i array, det som faktiskt testas är arrayens "inre element" för att se vilken typ det är.
Nu föreslår själva dokumentationen detta JavaScript-test med $where
:
.find({ "$where": "return Array.isArray(this.author)" })
Men jag tycker att det är ganska hemskt eftersom det finns ett bättre sätt.
Tricket är i "dot notation", där du frågar efter 0
indexelement för arrayen till $exists
.find({ "author.0": { "$exists": true } })
Vilket bara är det grundläggande fallet att om elementet "0:e" finns så är fältet närvarande och data är därför en array.
När du väl förstår den logiska premissen är det ett ganska enkelt test. Det enda som inte kan matchas med det är en "verkligen tom" array, i vilket fall du kan falla tillbaka till JavaScript-alternativet om det behövs. Men detta kan faktiskt använda ett index, så det skulle vara att föredra att använda den senare formen.