MongoDB中的$strLenBytes与$strLenCP:有什么区别?

发布于

MongoDB在其聚合管道框架中包含和运算符。这些运算符做类似但略有不同的事情。在某些情况下,两者将返回完全相同的结果,而在其他情况下,结果会有所不同。$strLenBytes``$strLenCP

以下是这两个运算符之间区别的快速概述。

区别

以下是每个运算符的定义:

  • $strLenBytes返回指定字符串中 UTF-8 编码字节数
  • $strLenCP返回指定字符串中 UTF-8 码位的数目。

请注意粗体字的差异。一个返回_字节_数,另一个返回_代码点_数。

处理英语字符串时,字节数通常与码位数相同。每个代码点将使用一个字节。

但是,在使用使用不同 Unicode 块的其他语言时,您可能会发现字节数增加到两个或三个字节。在使用其他 Unicode 代码点(如符号、表情符号等)时也是如此。在某些情况下,单个字符可能使用 4 个字节。

例

假设我们有一个包含以下文档的集合:unicode

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

现在让我们将两者应用于数据字段:$strLenBytes``$strLenCP

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

输出:

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

我们可以看到所有字符只使用一个码位,但第一个文档使用两个字节,另外两个文档各使用三个字节。

英文字符

假设我们有一个包含以下文档的集合:english

{ “_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” }

现在让我们将两者应用于数据字段:$strLenBytes``$strLenCP

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

Result:

{ “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 }

在这种情况下,所有字符都使用一个码位和一个字节。

泰语字符

下面是一个使用泰语字符的示例,用于演示并非所有语言都为每个代码点使用一个字节。

假设我们有一个包含以下文档的集合:thai

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

以下是我们将两者应用于数据字段时发生的情况:$strLenBytes``$strLenCP

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

输出:

{ "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 }