sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB $indexOfBytes

I MongoDB, $indexOfBytes aggregeringspipeline-operatorn söker i en sträng efter en förekomst av en delsträng och returnerar UTF-8-byteindex för den första förekomsten.

UTF-byteindexet är nollbaserat (dvs. det börjar vid 0 ).

Syntax

Syntaxen ser ut så här:

{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] }

Var:

  • är strängen att söka.
  • är den delsträng du vill hitta i strängen.
  • är ett valfritt argument som anger en startindexposition för sökningen. 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.

Om det angivna värdet inte hittas, $indexOfBytes 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 test med följande dokument:

{ "_id" : 1, "data" : "c 2021" }
{ "_id" : 2, "data" : "© 2021" }
{ "_id" : 3, "data" : "ไม้เมือง" }

Här är ett exempel på hur du använder $indexOfBytes till dessa dokument:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "2021" ] }
          }
     }
   ]
)

Resultat:

{ "data" : "c 2021", "result" : 2 }
{ "data" : "© 2021", "result" : 3 }
{ "data" : "ไม้เมือง", "result" : -1 }

Vi kan se att de två första dokumenten gav olika resultat, även om delsträngen verkar vara i samma position för varje dokument. I det första dokumentet hittades understrängen vid byteindexposition 2 , medan det andra dokumentet hade det på 3 .

Anledningen till detta är att copyright-symbolen (© ) i det andra dokumentet tar upp 2 byte. c tecken (i det första dokumentet) använder bara 1 byte. Mellanslagstecknet använder också 1 byte.

Resultatet av $indexOfBytes är nollbaserat (indexet börjar på 0 ), och så får vi resultatet 2 och 3 respektive.

När det gäller det tredje dokumentet hittades inte understrängen alls, så resultatet är -1 .

Här är ett annat exempel, förutom den här gången söker vi efter ett thailändskt tecken:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "เ" ] }
          }
     }
   ]
)

Resultat:

{ "data" : "c 2021", "result" : -1 }
{ "data" : "© 2021", "result" : -1 }
{ "data" : "ไม้เมือง", "result" : 9 }

I det här fallet sökte vi efter ett tecken som visas på den tredje positionen i det tredje dokumentet, och dess UTF-8-byteindex kommer tillbaka som 9 .

Detta beror på att i det här fallet använder varje tecken 3 byte. Men det andra tecknet har ett diakritiskt tecken, som också är 3 byte. Därför använder de två första tecknen (inklusive diakritiken) 9 byte. Med tanke på den nollbaserade indexeringen sträcker sig deras UTF-8-byteindex från 0 till 8 . Det betyder att det tredje tecknet börjar på position 9 .

Se MongoDB $strLenBytes för ett exempel som returnerar antalet byte för varje tecken i just den här strängen.

Ange en startposition

Du kan ange ett tredje argument för att ange en startindexposition för sökningen.

Anta att vi har följande dokument:

{ "_id" : 4, "data" : "ABC XYZ ABC" }

Här är ett exempel på hur du använder $indexOfBytes med en startposition:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
          }
     }
   ]
)

Resultat:

{ "data" : "ABC XYZ ABC", "result" : 8 }

I det här fallet returnerades den andra instansen av delsträngen. Detta beror på att vi startade sökningen vid position 1 , och den första instansen av delsträngen börjar vid position 0 (före startpositionen för sökningen).

Om startpositionen är ett tal större än strängens bytelängd eller större än slutpositionen, $indexOfBytes returnerar -1 .

Om det är ett negativt tal, $indexOfBytes returnerar ett fel.

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.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
          }
     }
   ]
)

Resultat:

{ "data" : "ABC XYZ ABC", "result" : -1 }

Resultatet är -1 vilket betyder att delsträngen inte hittades. Det beror på att vi började vår sökning på position 0 och avslutade den på position 5 , därför inte fånga understrängen.

Så här händer om vi ökar slutindexpositionen:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
          }
     }
   ]
)

Resultat:

{ "data" : "ABC XYZ ABC", "result" : 4 }

Den här gången inkluderades värdet och dess indexposition returnerades.

Om slutpositionen är ett nummer mindre än startpositionen, $indexOfBytes returnerar -1 .

Om det är ett negativt tal, $indexOfBytes returnerar ett fel.

Fält saknas

Om fältet inte finns i dokumentet, $indexOfBytes returnerar null .

Anta att vi har följande dokument:

{ "_id" : 5 }

Det här är vad som händer när vi använder $indexOfBytes :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 5 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Resultat:

{ "result" : null }

Nullvärden

Om det första argumentet är null , $indexOfBytes returnerar null .

Anta att vi har följande dokument:

{ "_id" : 6, "data" : null }

Det här är vad som händer när vi använder $indexOfBytes :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 6 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Resultat:

{ "data" : null, "result" : null }

Men när det andra argumentet (d.v.s. delsträngen) är null , returneras ett fel:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", null ] }
          }
     }
   ]
)

Resultat:

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfBytes requires a string as the second argument, found: null",
	"code" : 40092,
	"codeName" : "Location40092"
} : 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

Fel datatyp

Om det första argumentet är fel datatyp (dvs. det löser sig inte till en sträng), $indexOfBytes returnerar ett fel.

Anta att vi har följande dokument:

{ "_id" : 7, "data" : 123 }

Det här är vad som händer när vi använder $indexOfBytes till det dokumentet:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 7 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Resultat:

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfBytes requires a string as the first argument, found: double",
	"code" : 40091,
	"codeName" : "Location40091"
} : 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 $indexOfBytes en sträng som första argument .


  1. Tips för att lagra MongoDB-säkerhetskopior i molnet

  2. Redis klientbiblioteksrekommendationer för användning från Scala

  3. Konfigurera singleton-anslutning med node.js och mongo

  4. NodeJS + ExpressJS + RedisStore-session är odefinierad