sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB $substrBytes

V MongoDB, $substrBytes Operátor agregačního kanálu vrací podřetězec řetězce na základě zadaných indexů bajtů kódovaných UTF-8.

Syntaxe

Syntaxe vypadá takto:

{ $substrBytes: [ <string expression>, <byte index>, <byte count> ] }

Kde:

  • <string expression> je řetězec. Může to být jakýkoli platný výraz, pokud se překládá na řetězec.
  • <byte index> je místo, kde začít podřetězec. Může to být jakýkoli platný výraz, pokud se převede na nezáporné celé číslo nebo číslo, které lze reprezentovat jako celé číslo.
  • <byte count> udává, kolik bajtů má podřetězec pokračovat. Může to být jakýkoli platný výraz, pokud se převede na nezáporné celé číslo nebo číslo, které lze reprezentovat jako celé číslo.

Příklad

Představte si, že máme kolekci nazvanou tests s následujícím dokumentem:

{ "_id" : 1, "data" : "Red Firetruck" }

Můžeme použít $substrBytes takhle:

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

Výsledek:

{ "data" : "Red Firetruck", "result" : "Red" }

Index začíná na nule, takže náš podřetězec začal na začátku řetězce a pokračoval po dobu tří bajtů.

V tomto případě používáme anglické znaky a každý znak je jeden bajt. To nám usnadňuje spočítat, kolik bajtů použít.

Uveďme další příklad:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result_1: { $substrBytes: [ "$data", 4, 4 ] },
            result_2: { $substrBytes: [ "$data", 8, 5 ] },
            result_3: { $substrBytes: [ "$data", 8, 20 ] }
          }
     }
   ]
).pretty()

Výsledek:

{
	"data" : "Red Firetruck",
	"result_1" : "Fire",
	"result_2" : "truck",
	"result_3" : "truck"
}

Všimněte si, že v našem třetím výsledku jsme zadali více bajtů, než bylo k dispozici, ale jednoduše vrátil všechny znaky na konec řetězce.

Vícebajtové znaky

Některé znaky používají více než jeden bajt. Někdo používá dvě, někdo tři a někdo dokonce čtyři.

Zde je příklad dokumentu, který obsahuje spoustu symbolů:

{ "_id" : 2, "data" : "©♡★✪☆" }

Každý z těchto znaků používá více než jeden bajt. To znamená, že při extrakci podřetězce musíme být opatrní. Musíme si být jisti, že náš výchozí bod nezačíná v polovině postavy. Pokud ano, dojde k chybě. Stejně tak musíme zajistit, aby náš koncový bod neskončil v polovině postavy.

Prozatím použijeme $substrBytes aniž by došlo k chybě:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 2 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            bytes: { $strLenBytes: [ "$data" ] },
            result: { $substrBytes: [ "$data", 0, 5 ] }
          }
     }
   ]
)

Výsledek:

{ "data" : "©♡★✪☆", "bytes" : 14, "result" : "©♡" }

Na základě našeho výchozího bodu 0 a naše byte délka 5 , dostaneme dva znaky v naší výsledkové sadě. Můžeme tedy vidět, že první dva znaky používají 5 bajtů.

V tomto příkladu jsem také použil $strLenBytes vrátit celkový počet bajtů v řetězci. Udělal jsem to hlavně proto, abych ukázal, že těchto pět znaků používá 14 bajtů (více bajtů na znak).

Zde je mírně upravený příklad, který vrací každý ze dvou vrácených znaků:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 2 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            r1: { $substrBytes: [ "$data", 0, 2 ] },
            r2: { $substrBytes: [ "$data", 2, 3 ] }
          }
     }
   ]
)

Výsledek:

{ "data" : "©♡★✪☆", "r1" : "©", "r2" : "♡" }

Vidíme, že první znak používá dva bajty a druhý znak tři.

Špatný výchozí bod

Pokud je váš výchozí bod v polovině postavy, dojde k chybě.

Příklad:

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

Výsledek:

Error: command failed: {
	"ok" : 0,
	"errmsg" : "$substrBytes:  Invalid range, starting index is a UTF-8 continuation byte.",
	"code" : 28656,
	"codeName" : "Location28656"
} : 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

Tato chyba nám říká, že starting index is a UTF-8 continuation byte . Jinými slovy, pokusili jsme se začít v polovině postavy.

Špatný koncový bod

Stejné je to s koncovým bodem. Pokud je váš koncový bod v polovině znaku, dojde k chybě.

Příklad:

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

Výsledek:

Error: command failed: {
	"ok" : 0,
	"errmsg" : "$substrBytes:  Invalid range, ending index is in the middle of a UTF-8 character.",
	"code" : 28657,
	"codeName" : "Location28657"
} : 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

Tentokrát nám říká, že ending index is in the middle of a UTF-8 character .


  1. MongoDB $indexOfArray

  2. Redis klíč úložiště bez hodnoty

  3. Je s Redis Cluster možné pouze předat hash tagy eval?

  4. vlastní kompilace redis-client selhává