MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB $indexOfBytes

W MongoDB $indexOfBytes Operator potoku agregacji przeszukuje ciąg w poszukiwaniu wystąpienia podciągu i zwraca indeks bajtów UTF-8 pierwszego wystąpienia.

Indeks bajtów UTF jest liczony od zera (tzn. zaczyna się od 0 ).

Składnia

Składnia wygląda tak:

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

Gdzie:

  • jest ciągiem do przeszukania.
  • jest podciągiem, który chcesz znaleźć w ciągu.
  • jest opcjonalnym argumentem, który określa początkową pozycję indeksu wyszukiwania. 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.

Jeśli podana wartość nie zostanie znaleziona, $indexOfBytes 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 test z następującymi dokumentami:

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

Oto przykład zastosowania $indexOfBytes do tych dokumentów:

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

Wynik:

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

Widzimy, że pierwsze dwa dokumenty dały różne wyniki, mimo że podciąg wydaje się znajdować w tym samym miejscu dla każdego dokumentu. W pierwszym dokumencie podciąg został znaleziony na pozycji indeksu bajtów 2 , podczas gdy drugi dokument miał go w 3 .

Powodem tego jest to, że symbol praw autorskich (© ) w drugim dokumencie zajmuje 2 bajty. c znak (w pierwszym dokumencie) wykorzystuje tylko 1 bajt. Spacja również wykorzystuje 1 bajt.

Wynik $indexOfBytes jest liczony od zera (indeks zaczyna się od 0 ), więc otrzymujemy wynik 2 i 3 odpowiednio.

Jeśli chodzi o trzeci dokument, podciąg w ogóle nie został znaleziony, więc wynik to -1 .

Oto kolejny przykład, ale tym razem szukamy znaku tajskiego:

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

Wynik:

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

W tym przypadku szukaliśmy znaku, który pojawia się na trzeciej pozycji w trzecim dokumencie, a jego indeks bajtowy UTF-8 powraca jako 9 .

Dzieje się tak, ponieważ w tym przypadku każdy znak zajmuje 3 bajty. Ale drugi znak ma znak diakrytyczny, który również ma 3 bajty. Dlatego pierwsze dwa znaki (w tym znaki diakrytyczne) zajmują 9 bajtów. Biorąc pod uwagę indeksowanie od zera, ich indeksy bajtowe UTF-8 wahają się od 0 do 8 . Oznacza to, że trzeci znak zaczyna się na pozycji 9 .

Zobacz MongoDB $strLenBytes na przykład, który zwraca liczbę bajtów dla każdego znaku w tym konkretnym ciągu.

Określ pozycję startową

Możesz podać trzeci argument, aby określić początkową pozycję indeksu wyszukiwania.

Załóżmy, że mamy następujący dokument:

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

Oto przykład zastosowania $indexOfBytes z pozycją wyjściową:

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

Wynik:

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

W tym przypadku zostało zwrócone drugie wystąpienie podciągu. Dzieje się tak, ponieważ rozpoczęliśmy wyszukiwanie na pozycji 1 , a pierwsze wystąpienie podciągu zaczyna się od pozycji 0 (przed pozycją początkową wyszukiwania).

Jeśli pozycja początkowa jest liczbą większą niż długość ciągu w bajtach lub większą niż pozycja końcowa, $indexOfBytes zwraca -1 .

Jeśli jest to liczba ujemna, $indexOfBytes zwraca błąd.

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

Wynik:

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

Wynik to -1 co oznacza, że ​​podciąg nie został znaleziony. To dlatego, że rozpoczęliśmy nasze poszukiwania na pozycji 0 i zakończył na pozycji 5 , dlatego nie przechwytuje podciągu.

Oto, co się stanie, jeśli zwiększymy końcową pozycję indeksu:

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

Wynik:

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

Tym razem wartość została uwzględniona, a jej pozycja indeksu zwrócona.

Jeśli pozycja końcowa jest liczbą mniejszą niż pozycja początkowa, $indexOfBytes zwraca -1 .

Jeśli jest to liczba ujemna, $indexOfBytes zwraca błąd.

Brakujące pola

Jeśli pola nie ma w dokumencie, $indexOfBytes zwraca null .

Załóżmy, że mamy następujący dokument:

{ "_id" : 5 }

Oto, co się dzieje, gdy zastosujemy $indexOfBytes :

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

Wynik:

{ "result" : null }

Wartości puste

Jeśli pierwszym argumentem jest null , $indexOfBytes zwraca null .

Załóżmy, że mamy następujący dokument:

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

Oto, co się dzieje, gdy zastosujemy $indexOfBytes :

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

Wynik:

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

Jednak gdy drugim argumentem (tj. podciągiem) jest null , zwracany jest błąd:

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

Wynik:

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

Niewłaściwy typ danych

Jeśli pierwszy argument jest niewłaściwym typem danych (tj. nie jest tłumaczony na łańcuch), $indexOfBytes zwraca błąd.

Załóżmy, że mamy następujący dokument:

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

Oto, co się dzieje, gdy zastosujemy $indexOfBytes do tego dokumentu:

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

Wynik:

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

Jak stwierdza komunikat o błędzie, $indexOfBytes wymaga ciągu jako pierwszego argumentu .


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Automatycznie generowane pole dla MongoDB przy użyciu Spring Boot

  2. Mongoose:porównania identyfikatorów obiektów kończą się niepowodzeniem

  3. grupuj według zapytań dotyczących kolekcji meteor

  4. Jak wysłać zapytanie do MongoDB za pomocą like

  5. Używanie .sort z PyMongo