In MongoDB is de $indexOfCP
aggregatiepijplijnoperator zoekt in een tekenreeks naar een exemplaar van een subtekenreeks en retourneert de UTF-codepuntindex van het eerste exemplaar.
De UTF-codepuntindex is gebaseerd op nul (d.w.z. hij begint bij 0
).
Syntaxis
De syntaxis gaat als volgt:
{ $indexOfCP: [ <string expression>, <substring expression>, <start>, <end> ] }
Waar:
<string expression>
is de tekenreeks om te zoeken.<substring expression>
is de substring die je in de string wilt vinden.<start>
is een optioneel argument dat een startindexpositie voor de zoekopdracht specificeert. Kan elke geldige uitdrukking zijn die oplost in een niet-negatief geheel getal.<end>
is een optioneel argument dat een eindindexpositie voor de zoekopdracht specificeert. Kan elke geldige uitdrukking zijn die oplost in een niet-negatief geheel getal.
Als de opgegeven waarde niet wordt gevonden, $indexOfCP
retourneert -1
.
Als er meerdere exemplaren van de opgegeven waarde zijn, wordt alleen de eerste geretourneerd.
Voorbeeld
Stel dat we een verzameling hebben met de naam test
met de volgende documenten:
{ "_id" : 1, "data" : "c 2021" } { "_id" : 2, "data" : "© 2021" } { "_id" : 3, "data" : "ไม้เมือง" }
Hier is een voorbeeld van het toepassen van $indexOfCP
naar die documenten:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "2021" ] }
}
}
]
)
Resultaat:
{ "data" : "c 2021", "result" : 2 } { "data" : "© 2021", "result" : 2 } { "data" : "ไม้เมือง", "result" : -1 }
In de eerste twee documenten werd de substring gevonden op UTF-codepuntindexpositie 2
. Gegeven $indexOfCP
resultaten zijn gebaseerd op nul (de index begint bij 0
) de positie 2 vertegenwoordigt het derde codepunt.
Dit is een ander resultaat dan wat we zouden krijgen als we $indexOfBytes
gebruiken , omdat het copyright-symbool (©
) in het tweede document neemt 2 bytes in beslag. Maar het gebruikt slechts één codepunt, wat hetzelfde is als wat de letter c
gebruikt.
Wat betreft het derde document, de substring werd helemaal niet gevonden, en dus is het resultaat -1
.
Hier is nog een voorbeeld, maar deze keer zoeken we naar een Thais karakter:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "เ" ] }
}
}
]
)
Resultaat:
{ "data" : "c 2021", "result" : -1 } { "data" : "© 2021", "result" : -1 } { "data" : "ไม้เมือง", "result" : 3 }
In dit geval hebben we gezocht naar een teken dat in het derde document staat, en de UTF-8-codepuntindex komt terug als 3
. Gegeven $indexOfCP
resultaten zijn gebaseerd op nul, dit betekent dat dit het vierde codepunt is.
Dit komt omdat het tweede teken een diakritisch teken heeft, wat ook een codepunt is. Daarom is het eerste teken één codepunt en het tweede teken twee codepunten (inclusief het diakritische teken), wat gelijk is aan drie. Dit betekent dat ons karakter begint op de vierde positie (dat is codepuntnummer 3
, vanwege indextelling die begint bij 0
).
Zie MongoDB $strLenCP
voor een voorbeeld dat het aantal codepunten voor elk teken in deze specifieke tekenreeks retourneert. En zie MongoDB $strLenBytes
om het aantal bytes in dezelfde string te zien.
Geef een startpositie op
U kunt een derde argument opgeven om een startindexpositie voor de zoekopdracht op te geven.
Stel dat we het volgende document hebben:
{ "_id" : 4, "data" : "ABC XYZ ABC" }
Hier is een voorbeeld van het toepassen van $indexOfCP
met een startpositie:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "ABC", 1 ] }
}
}
]
)
Resultaat:
{ "data" : "ABC XYZ ABC", "result" : 8 }
In dit geval is het tweede exemplaar van de subtekenreeks geretourneerd. Dit komt omdat we de zoekopdracht zijn begonnen op positie 1
, en de eerste instantie van de substring begint op positie 0
(vóór de startpositie voor de zoekopdracht).
Als de startpositie een getal is dat groter is dan de tekenreeks of groter is dan de eindpositie, $indexOfCP
retourneert -1
.
Als het een negatief getal is, $indexOfCP
geeft een fout terug.
Geef een eindpositie op
U kunt ook een vierde argument opgeven om de eindindexpositie voor de zoekopdracht te specificeren.
Als u dit argument geeft, moet u ook een startpositie opgeven. Als u dit niet doet, wordt dit argument als het startpunt geïnterpreteerd.
Voorbeeld:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "XYZ", 0, 3 ] }
}
}
]
)
Resultaat:
{ "data" : "ABC XYZ ABC", "result" : -1 }
Het resultaat is -1
wat betekent dat de substring niet is gevonden. Dat komt omdat we onze zoektocht begonnen op positie 0
en eindigde op positie 3
, dus de substring niet vastleggen.
Dit is wat er gebeurt als we de eindindexpositie verhogen:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "XYZ", 0, 5 ] }
}
}
]
)
Resultaat:
{ "data" : "ABC XYZ ABC", "result" : 4 }
Deze keer werd de waarde opgenomen en keerde de indexpositie terug.
Als de eindpositie een getal kleiner is dan de beginpositie, $indexOfCP
retourneert -1
.
Als het een negatief getal is, $indexOfCP
geeft een fout terug.
Ontbrekende velden
Als het veld niet in het document staat, $indexOfCP
retourneert null
.
Stel dat we het volgende document hebben:
{ "_id" : 5 }
Dit is wat er gebeurt als we $indexOfCP
toepassen :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "XYZ" ] }
}
}
]
)
Resultaat:
{ "result" : null }
Null-waarden
Als het eerste argument null
. is , $indexOfCP
retourneert null
.
Stel dat we het volgende document hebben:
{ "_id" : 6, "data" : null }
Dit is wat er gebeurt als we $indexOfCP
toepassen :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "XYZ" ] }
}
}
]
)
Resultaat:
{ "data" : null, "result" : null }
Echter, wanneer het tweede argument (d.w.z. de substring) null
. is , er wordt een fout geretourneerd:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", null ] }
}
}
]
)
Resultaat:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$indexOfCP requires a string as the second argument, found: null", "code" : 40094, "codeName" : "Location40094" } : 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
Onjuist gegevenstype
Als het eerste argument het verkeerde gegevenstype is (d.w.z. het wordt niet omgezet in een tekenreeks), $indexOfCP
geeft een fout terug.
Stel dat we het volgende document hebben:
{ "_id" : 7, "data" : 123 }
Dit is wat er gebeurt als we $indexOfCP
toepassen naar dat document:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfCP: [ "$data", "XYZ" ] }
}
}
]
)
Resultaat:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$indexOfCP requires a string as the first argument, found: double", "code" : 40093, "codeName" : "Location40093" } : 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
Zoals de foutmelding aangeeft, vereist $indexOfCP requires a string as the first argument
.