W MongoDB $indexOfArray
Operator potoku agregacji przeszukuje tablicę pod kątem wystąpienia określonej wartości i zwraca indeks tablicy pierwszego wystąpienia.
Składnia
Składnia wygląda tak:
{ $indexOfArray: [ <array expression>, <search expression>, <start>, <end> ] }
Gdzie:
jest tablicą do przeszukania.
jest wartością, którą chcesz znaleźć w tablicy.jest opcjonalnym argumentem, który określa punkt początkowy wyszukiwania w tablicy. Może być dowolnym prawidłowym wyrażeniem, które prowadzi do nieujemnej liczby całkowitej.
jest opcjonalnym argumentem, który określa końcową pozycję indeksu wyszukiwania. Może być dowolnym prawidłowym wyrażeniem, które prowadzi do nieujemnej liczby całkowitej.
W MongoDB tablice są liczone od zera, więc licznik indeksów zaczyna się od zera (0
).
Jeśli określona wartość nie zostanie znaleziona, $indexOfArray
zwraca -1
.
Jeśli istnieje wiele wystąpień określonej wartości, zwracana jest tylko pierwsza.
Przykład
Załóżmy, że mamy kolekcję o nazwie produkty
z następującymi dokumentami:
{ "_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 ] }
Oto przykład zastosowania $indexOfArray
do tych dokumentów:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Wynik:
{ "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 }
W pierwszych dwóch dokumentach wartość wyszukiwania została znaleziona na pozycji 0
(tablice są od zera).
W trzecim dokumencie został znaleziony na pozycji 1
. Zauważ, że wyszukiwanie dotyczyło dokładnego dopasowania. Nie zwrócił pozycji 0
, mimo że wartość na pozycji 0
zawiera wartość wyszukiwania (np. XXS
zawiera XS
).
Wartość wyszukiwania nie została znaleziona w dwóch ostatnich dokumentach, więc -1
został zwrócony.
Oto kolejny przykład, ale tym razem szukamy wartości liczbowej:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15 ] }
}
}
]
)
Wynik:
{ "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 }
Określ pozycję startową
Możesz podać trzeci argument, aby określić początkową pozycję indeksu wyszukiwania.
Przykład:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15, 1 ] }
}
}
]
)
Wynik:
{ "sizes" : [ 10, 12, 15 ], "result" : 2 } { "sizes" : [ 15, 16, 20 ], "result" : -1 }
W tym przypadku wyrażenie wyszukiwania nie zostało znalezione w drugim dokumencie (dokument 5). Dzieje się tak, ponieważ rozpoczęliśmy wyszukiwanie na pozycji 1
, i chociaż ten dokument zawiera wyrażenie wyszukiwania, znajduje się na pozycji 0
(przed pozycją początkową wyszukiwania).
Określ pozycję końcową
Możesz również podać czwarty argument, aby określić końcową pozycję indeksu wyszukiwania.
Jeśli podasz ten argument, musisz również podać pozycję początkową. Jeśli tego nie zrobisz, ten argument zostanie zinterpretowany jako punkt wyjścia.
Przykład:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 1 ] }
}
}
]
)
Wynik:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }
Trzeci dokument zwrócił -1
co oznacza, że wyszukiwane wyrażenie nie zostało znalezione.
Oto, co się stanie, jeśli zwiększymy końcową pozycję indeksu o 1:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 2 ] }
}
}
]
)
Wynik:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }
Tym razem wartość została uwzględniona, a jej pozycja indeksu zwrócona.
Puste tablice
Wyszukiwanie pustej tablicy zwraca -1
.
db.products.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Wynik:
{ "sizes" : [ ], "result" : -1 }
Brakujące pola
Jeśli pola nie ma w dokumencie, $indexOfArray
zwraca null
.
Załóżmy, że mamy następujący dokument:
{ "_id" : 8, "prod" : "Map" }
Oto, co się dzieje, gdy zastosujemy $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Wynik:
{ "result" : null }
Wartości puste
Jeśli wyrażenie tablicowe ma wartość null
(zamiast tablicy), $indexOfArray
zwraca null
.
Załóżmy, że mamy następujący dokument:
{ "_id" : 7, "prod" : "Lap", "sizes" : null }
Oto, co się dzieje, gdy zastosujemy $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Wynik:
{ "sizes" : null, "result" : null }
Jednak gdy wyrażenie wyszukiwania ma wartość null
, wynik to -1
, chyba że wyrażenie tablicowe jest również null
lub brakuje jej pola:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5, 6, 7, 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", null ] }
}
}
]
)
Wynik:
{ "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 }
Niewłaściwy typ danych
Jeśli wyrażenie tablicowe ma niewłaściwy typ danych, $indexOfArray
zwraca błąd.
Załóżmy, że mamy następujący dokument:
{ "_id" : 9, "prod" : "Box", "sizes" : "XXL" }
Oto, co się dzieje, gdy zastosujemy $indexOfArray
do tego dokumentu:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 9 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XXL" ] }
}
}
]
)
Wynik:
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
Jak stwierdza komunikat o błędzie, $indexOfArray wymaga tablicy jako pierwszego argumentu
.