I MongoDB, $indexOfArray
aggregeringspipeline-operatören söker i en array efter en förekomst av ett specificerat värde och returnerar arrayindexet för den första förekomsten.
Syntax
Syntaxen ser ut så här:
{ $indexOfArray: [ <array expression>, <search expression>, <start>, <end> ] }
Var:
är arrayen att söka.
är värdet du vill hitta i arrayen.är ett valfritt argument som anger en startpunkt för sökning i arrayen. Kan vara vilket giltigt uttryck som helst som löser sig till ett icke-negativt heltal.
är ett valfritt argument som anger en slutindexposition för sökningen. Kan vara vilket giltigt uttryck som helst som löser sig till ett icke-negativt heltal.
I MongoDB är arrayer nollbaserade, så indexräkningen börjar på noll (0
).
Om det angivna värdet inte hittas, $indexOfArray
returnerar -1
.
Om det finns flera instanser av det angivna värdet, returneras bara den första.
Exempel
Anta att vi har en samling som heter produkter
med följande dokument:
{ "_id" : 1, "prod" : "Bat", "sizes" : [ "XS", "M", "L" ] } { "_id" : 2, "prod" : "Hat", "sizes" : [ "XS", "S", "L", "XL" ] } { "_id" : 3, "prod" : "Cap", "sizes" : [ "XXS", "XS", "M", "XL" ] } { "_id" : 4, "prod" : "Zap", "sizes" : [ 10, 12, 15 ] } { "_id" : 5, "prod" : "Tap", "sizes" : [ 15, 16, 20 ] }
Här är ett exempel på hur du använder $indexOfArray
till dessa dokument:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Resultat:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 } { "sizes" : [ 10, 12, 15 ], "result" : -1 } { "sizes" : [ 15, 16, 20 ], "result" : -1 }
I de två första dokumenten hittades sökvärdet vid position 0
(matriser är nollbaserade).
I det tredje dokumentet hittades den på position 1
. Lägg märke till att sökningen var efter en exakt matchning. Den returnerade inte position 0
, även om värdet vid position 0
innehåller sökvärdet (dvs. XXS
innehåller XS
).
Sökvärdet hittades inte i de två senaste dokumenten, och därför -1
returnerades.
Här är ett annat exempel, förutom den här gången söker vi efter ett numeriskt värde:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15 ] }
}
}
]
)
Resultat:
{ "sizes" : [ "XS", "M", "L" ], "result" : -1 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : -1 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 } { "sizes" : [ 10, 12, 15 ], "result" : 2 } { "sizes" : [ 15, 16, 20 ], "result" : 0 }
Ange en startposition
Du kan ange ett tredje argument för att ange en startindexposition för sökningen.
Exempel:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15, 1 ] }
}
}
]
)
Resultat:
{ "sizes" : [ 10, 12, 15 ], "result" : 2 } { "sizes" : [ 15, 16, 20 ], "result" : -1 }
I det här fallet hittades inte sökuttrycket i det andra dokumentet (dokument 5). Detta beror på att vi startade sökningen vid position 1
, och även om det dokumentet innehåller sökuttrycket är det på position 0
(före startpositionen för sökningen).
Ange en slutposition
Du kan också ange ett fjärde argument för att ange slutindexpositionen för sökningen.
Om du ger detta argument måste du också ange en utgångsposition. Underlåtenhet att göra det kommer att resultera i att detta argument tolkas som utgångspunkten.
Exempel:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 1 ] }
}
}
]
)
Resultat:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }
Det tredje dokumentet returnerade -1
vilket betyder att sökuttrycket inte hittades.
Så här händer om vi ökar slutindexpositionen med 1:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 2 ] }
}
}
]
)
Resultat:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }
Den här gången inkluderades värdet och dess indexposition returnerades.
Tömma arrayer
Att söka i en tom array returnerar -1
.
db.products.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Resultat:
{ "sizes" : [ ], "result" : -1 }
Fält saknas
Om fältet inte finns i dokumentet, $indexOfArray
returnerar null
.
Anta att vi har följande dokument:
{ "_id" : 8, "prod" : "Map" }
Här är vad som händer när vi använder $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Resultat:
{ "result" : null }
Nullvärden
Om array-uttrycket är null
(istället för en array), $indexOfArray
returnerar null
.
Anta att vi har följande dokument:
{ "_id" : 7, "prod" : "Lap", "sizes" : null }
Här är vad som händer när vi använder $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Resultat:
{ "sizes" : null, "result" : null }
Men när sökuttrycket är null
, resultatet är -1
, om inte arrayuttrycket också är null
eller dess fält saknas:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5, 6, 7, 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", null ] }
}
}
]
)
Resultat:
{ "sizes" : [ "XS", "M", "L" ], "result" : -1 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : -1 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 } { "sizes" : [ 10, 12, 15 ], "result" : -1 } { "sizes" : [ 15, 16, 20 ], "result" : -1 } { "sizes" : [ ], "result" : -1 } { "sizes" : null, "result" : null } { "result" : null }
Fel datatyp
Om arrayuttrycket är fel datatyp, $indexOfArray
returnerar ett fel.
Anta att vi har följande dokument:
{ "_id" : 9, "prod" : "Box", "sizes" : "XXL" }
Här är vad som händer när vi använder $indexOfArray
till det dokumentet:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 9 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XXL" ] }
}
}
]
)
Resultat:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$indexOfArray requires an array as a first argument, found: string", "code" : 40090, "codeName" : "Location40090" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
Som felmeddelandet säger kräver $indexOfArray en array som ett första argument
.