$substrBytes (aggregation)

Definition

  • $substrBytes

New in version 3.4.

Returns the substring of a string. The substring starts with thecharacter at the specified UTF-8 byte index (zero-based) in thestring and continues for the number of bytes specified.

$substrBytes has the following operatorexpression syntax:

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

FieldTypeDescriptionstring expressionstringThe string from which the substring will be extracted. string expressioncan be any valid expression aslong as it resolves to a string. For more information onexpressions, see Expressions.

If the argument resolves to a value of null or refers to a fieldthat is missing, $substrBytes returns an empty string.

If the argument does not resolve to a string or null norrefers to a missing field, $substrBytes returns an error.byte indexnumberIndicates the starting point of the substring. byte index can beany valid expression as long asit resolves to a non-negative integer or number that can berepresented as an integer (such as 2.0).

byte index cannot referto a starting index located in the middle of a multi-byte UTF-8character.byte countnumberCan be any valid expressionas long as it resolves to a non-negative integer or number that can berepresented as an integer (such as 2.0).

byte count can notresult in an ending index that is in the middle of a UTF-8 character.

Behavior

The $substrBytes operator uses the indexes of UTF-8encoded bytes where each code point, or character, may use between oneand four bytes to encode.

For example, US-ASCII characters are encoded using one byte. Characterswith diacritic markings and additional Latin alphabetical characters(i.e. Latin characters outside of the English alphabet) are encodedusing two bytes. Chinese, Japanese and Korean characters typicallyrequire three bytes, and other planes of unicode (emoji, mathematicalsymbols, etc.) require four bytes.

It is important to be mindful of the content in thestring expression because providing a byte index orbyte count located in the middle of a UTF-8 character will resultin an error.

$substrBytes differs from $substrCP in that$substrBytes counts the bytes of each character, whereas$substrCP counts the code points, or characters,regardless of how many bytes a character uses.

ExampleResults
  1. { $substrBytes: [ "abcde", 1, 2 ] }
  1. "bc"
  1. { $substrBytes: [ "Hello World!", 6, 5 ] }
  1. "World"
  1. { $substrBytes: [ "cafétéria", 0, 5 ] }
  1. "café"
  1. { $substrBytes: [ "cafétéria", 5, 4 ] }
  1. "tér"
  1. { $substrBytes: [ "cafétéria", 7, 3 ] }
Errors with message:"Error: Invalid range, starting index is a UTF-8 continuation byte."
  1. { $substrBytes: [ "cafétéria", 3, 1 ] }
Errors with message:"Error: Invalid range, ending index is in the middle of a UTF-8 character."

Example

Single-Byte Character Set

Consider an inventory collection with the following documents:

  1. { "_id" : 1, "item" : "ABC1", quarter: "13Q1", "description" : "product 1" }
  2. { "_id" : 2, "item" : "ABC2", quarter: "13Q4", "description" : "product 2" }
  3. { "_id" : 3, "item" : "XYZ1", quarter: "14Q2", "description" : null }

The following operation uses the $substrBytes operatorseparate the quarter value (containing only single byte US-ASCIIcharacters) into a yearSubstring and a quarterSubstring. ThequarterSubstring field represents the rest of the string from thespecified byte index following the yearSubstring. It iscalculated by subtracting the byte index from the length of thestring using $strLenBytes.

  1. db.inventory.aggregate(
  2. [
  3. {
  4. $project: {
  5. item: 1,
  6. yearSubstring: { $substrBytes: [ "$quarter", 0, 2 ] },
  7. quarterSubtring: {
  8. $substrBytes: [
  9. "$quarter", 2, { $subtract: [ { $strLenBytes: "$quarter" }, 2 ] }
  10. ]
  11. }
  12. }
  13. }
  14. ]
  15. )

The operation returns the following results:

  1. { "_id" : 1, "item" : "ABC1", "yearSubstring" : "13", "quarterSubtring" : "Q1" }
  2. { "_id" : 2, "item" : "ABC2", "yearSubstring" : "13", "quarterSubtring" : "Q4" }
  3. { "_id" : 3, "item" : "XYZ1", "yearSubstring" : "14", "quarterSubtring" : "Q2" }

Single-Byte and Multibyte Character Set

A collection named food contains the following documents:

  1. { "_id" : 1, "name" : "apple" }
  2. { "_id" : 2, "name" : "banana" }
  3. { "_id" : 3, "name" : "éclair" }
  4. { "_id" : 4, "name" : "hamburger" }
  5. { "_id" : 5, "name" : "jalapeño" }
  6. { "_id" : 6, "name" : "pizza" }
  7. { "_id" : 7, "name" : "tacos" }
  8. { "_id" : 8, "name" : "寿司sushi" }

The following operation uses the $substrBytes operator to create a threebyte menuCode from the name value:

  1. db.food.aggregate(
  2. [
  3. {
  4. $project: {
  5. "name": 1,
  6. "menuCode": { $substrBytes: [ "$name", 0, 3 ] }
  7. }
  8. }
  9. ]
  10. )

The operation returns the following results:

  1. { "_id" : 1, "name" : "apple", "menuCode" : "app" }
  2. { "_id" : 2, "name" : "banana", "menuCode" : "ban" }
  3. { "_id" : 3, "name" : "éclair", "menuCode" : "éc" }
  4. { "_id" : 4, "name" : "hamburger", "menuCode" : "ham" }
  5. { "_id" : 5, "name" : "jalapeño", "menuCode" : "jal" }
  6. { "_id" : 6, "name" : "pizza", "menuCode" : "piz" }
  7. { "_id" : 7, "name" : "tacos", "menuCode" : "tac" }
  8. { "_id" : 8, "name" : "寿司sushi", "menuCode" : "寿" }

See also

$substrCP