В MongoDB, $indexOfArray
Операторът на тръбопровода за агрегиране търси в масива среща с определена стойност и връща индекса на масива на първото появяване.
Синтаксис
Синтаксисът е така:
{ $indexOfArray: [ <array expression>, <search expression>, <start>, <end> ] }
Къде:
<array expression>
е масивът за търсене.<search expression>
е стойността, която искате да намерите в масива.<start>
е незадължителен аргумент, който определя начална точка, за която да се търси в масива. Може да бъде всеки валиден израз, който се разрешава до неотрицателно цяло число.<end>
е незадължителен аргумент, който определя крайна индексна позиция за търсенето. Може да бъде всеки валиден израз, който се разрешава до неотрицателно цяло число.
В MongoDB масивите са базирани на нула, така че броят на индексите започва от нула (0
).
Ако посочената стойност не е намерена, $indexOfArray
връща -1
.
Ако има няколко екземпляра на посочената стойност, се връща само първият.
Пример
Да предположим, че имаме колекция, наречена products
със следните документи:
{ "_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 ] }
Ето пример за прилагане на $indexOfArray
към тези документи:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Резултат:
{ "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 }
В първите два документа стойността за търсене е намерена на позиция 0
(масивите са базирани на нула).
В третия документ е намерен на позиция 1
. Забележете, че търсенето е за точно съвпадение. Не върна позиция 0
, въпреки че стойността на позиция 0
съдържа стойността за търсене (т.е. XXS
съдържа XS
).
Стойността за търсене не беше намерена в последните два документа и така -1
беше върнат.
Ето още един пример, освен този път ние търсим числова стойност:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15 ] }
}
}
]
)
Резултат:
{ "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 }
Посочете начална позиция
Можете да предоставите трети аргумент, за да посочите начална позиция на индекса за търсене.
Пример:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15, 1 ] }
}
}
]
)
Резултат:
{ "sizes" : [ 10, 12, 15 ], "result" : 2 } { "sizes" : [ 15, 16, 20 ], "result" : -1 }
В този случай изразът за търсене не е намерен във втория документ (документ 5). Това е така, защото започнахме търсенето на позиция 1
, и въпреки че този документ съдържа израза за търсене, той е на позиция 0
(преди началната позиция за търсене).
Посочете крайна позиция
Можете също да предоставите четвърти аргумент, за да посочите крайната позиция на индекса за търсене.
Ако предоставите този аргумент, трябва да посочите и начална позиция. Ако не го направите, този аргумент ще бъде интерпретиран като отправна точка.
Пример:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 1 ] }
}
}
]
)
Резултат:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }
Третият документ върна -1
което означава, че изразът за търсене не е намерен.
Ето какво се случва, ако увеличим позицията на крайния индекс с 1:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 2 ] }
}
}
]
)
Резултат:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }
Този път стойността беше включена и нейната индексна позиция беше върната.
Празни масиви
Търсенето в празен масив връща -1
.
db.products.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Резултат:
{ "sizes" : [ ], "result" : -1 }
Липсващи полета
Ако полето не е в документа, $indexOfArray
връща null
.
Да предположим, че имаме следния документ:
{ "_id" : 8, "prod" : "Map" }
Ето какво се случва, когато приложим $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Резултат:
{ "result" : null }
Нулеви стойности
Ако изразът на масива е null
(вместо масив), $indexOfArray
връща null
.
Да предположим, че имаме следния документ:
{ "_id" : 7, "prod" : "Lap", "sizes" : null }
Ето какво се случва, когато приложим $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Резултат:
{ "sizes" : null, "result" : null }
Въпреки това, когато изразът за търсене е null
, резултатът е -1
, освен ако изразът на масива също не е null
или полето му липсва:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5, 6, 7, 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", null ] }
}
}
]
)
Резултат:
{ "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 }
Грешен тип данни
Ако изразът на масива е грешен тип данни, $indexOfArray
връща грешка.
Да предположим, че имаме следния документ:
{ "_id" : 9, "prod" : "Box", "sizes" : "XXL" }
Ето какво се случва, когато приложим $indexOfArray
към този документ:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 9 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XXL" ] }
}
}
]
)
Резултат:
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
Както гласи съобщението за грешка, $indexOfArray requires an array as a first argument
.