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

$strLenBytes vs $strLenCP w MongoDB:Jaka jest różnica?

MongoDB zawiera $strLenBytes i $strLenCP operatorów w swojej strukturze potoku agregacji. Operatorzy ci robią podobną, ale nieco inną rzecz. W niektórych przypadkach oba zwrócą dokładnie ten sam wynik, podczas gdy w innych wyniki będą się różnić.

Oto krótki przegląd różnicy między tymi dwoma operatorami.

Różnica

Oto definicja każdego operatora:

  • $strLenBytes zwraca liczbę bajtów zakodowanych w UTF-8 w określonym ciągu
  • $strLenCP zwraca liczbę punktów kodowych UTF-8 w określonym ciągu.

Zwróć uwagę na różnicę pogrubioną czcionką. Jeden zwraca liczbę bajtów , druga zwraca liczbę punktów kodowych .

Podczas pracy z ciągami w języku angielskim liczba bajtów będzie zwykle taka sama jak liczba punktów kodowych. Każdy punkt kodowy użyje jednego bajtu.

Ale podczas pracy z innymi językami, które używają innego bloku Unicode, może się okazać, że liczba bajtów wzrośnie do dwóch lub trzech bajtów. Dotyczy to również pracy z innymi punktami kodu Unicode, takimi jak symbole, emoji itp. W niektórych przypadkach pojedynczy znak może mieć 4 bajty.

Przykład

Załóżmy, że mamy kolekcję o nazwie unicode z następującymi dokumentami:

{ "_id" : 1, "data" : "é" }
{ "_id" : 2, "data" : "©" }
{ "_id" : 3, "data" : "℘" }

A teraz zastosujmy oba $strLenBytes i $strLenCP do pola danych:

db.unicode.aggregate(
   [
     {
       $project:
          {
            _id: 0,
            data: 1,
            strLenCP: { $strLenCP: "$data" },
            strLenBytes: { $strLenBytes: "$data" }
          }
     }
   ]
)

Wynik:

{ "data" : "é", "strLenCP" : 1, "strLenBytes" : 2 }
{ "data" : "©", "strLenCP" : 1, "strLenBytes" : 2 }
{ "data" : "℘", "strLenCP" : 1, "strLenBytes" : 3 }

Widzimy, że wszystkie znaki używają tylko jednego punktu kodowego, ale pierwszy dokument używa dwóch bajtów, a pozostałe dwa dokumenty używają trzech bajtów.

Znaki angielskie

Załóżmy, że mamy kolekcję o nazwie english z następującymi dokumentami:

{ "_id" : 1, "data" : "Fast dog" }
{ "_id" : 2, "data" : "F" }
{ "_id" : 3, "data" : "a" }
{ "_id" : 4, "data" : "s" }
{ "_id" : 5, "data" : "t" }
{ "_id" : 6, "data" : " " }
{ "_id" : 7, "data" : "d" }
{ "_id" : 8, "data" : "o" }
{ "_id" : 9, "data" : "g" }

A teraz zastosujmy oba $strLenBytes i $strLenCP do pola danych:

db.english.aggregate(
   [
     {
       $project:
          {
            _id: 0,
            data: 1,
            strLenCP: { $strLenCP: "$data" },
            strLenBytes: { $strLenBytes: "$data" }
          }
     }
   ]
)

Wynik:

{ "data" : "Fast dog", "strLenCP" : 8, "strLenBytes" : 8 }
{ "data" : "F", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : "a", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : "s", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : "t", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : " ", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : "d", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : "o", "strLenCP" : 1, "strLenBytes" : 1 }
{ "data" : "g", "strLenCP" : 1, "strLenBytes" : 1 }

W takim przypadku wszystkie znaki używają jednego punktu kodowego i jednego bajtu.

Znaki tajskie

Oto przykład, który używa znaków tajskich, aby zademonstrować, że nie wszystkie języki używają jednego bajtu na punkt kodowy.

Załóżmy, że mamy kolekcję o nazwie thai z następującymi dokumentami:

{ "_id" : 1, "data" : "ไม้เมือง" }
{ "_id" : 2, "data" : "ไ" }
{ "_id" : 3, "data" : "ม้" }
{ "_id" : 4, "data" : "เ" }
{ "_id" : 5, "data" : "มื" }
{ "_id" : 6, "data" : "อ" }
{ "_id" : 7, "data" : "ง" }

Oto, co się dzieje, gdy zastosujemy oba $strLenBytes i $strLenCP do pola danych:

db.thai.aggregate(
   [
     {
       $project:
          {
            _id: 0,
            data: 1,
            strLenCP: { $strLenCP: "$data" },
            strLenBytes: { $strLenBytes: "$data" }
          }
     }
   ]
)

Wynik:

{ "data" : "ไม้เมือง", "strLenCP" : 8, "strLenBytes" : 24 }
{ "data" : "ไ", "strLenCP" : 1, "strLenBytes" : 3 }
{ "data" : "ม้", "strLenCP" : 2, "strLenBytes" : 6 }
{ "data" : "เ", "strLenCP" : 1, "strLenBytes" : 3 }
{ "data" : "มื", "strLenCP" : 2, "strLenBytes" : 6 }
{ "data" : "อ", "strLenCP" : 1, "strLenBytes" : 3 }
{ "data" : "ง", "strLenCP" : 1, "strLenBytes" : 3 }

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Tablica grupowa po odprężeniu i dopasowaniu

  2. Zastępowanie osadzonego dokumentu w tablicy w MongoDB

  3. Jak odzyskać zaktualizowany dokument z metody findOneAndUpdate?

  4. Jak znaleźć nazwę pola MongoDB na dowolnej głębokości?

  5. Jak przekonwertować pymongo.cursor.Cursor na dict?