MongoDB 有线协议
注意
本MongoDB传输协议规范根据 Creative Commons Attribution-NonCommercial-ShareAlike3.0 美国许可 获得许可。您不得出于任何商业目的使用或改编本材料,例如创建商业数据库或数据库即服务产品。
简介
MongoDB 传输协议是一种基于套接字的简易请求-响应式协议。客户端可通过常规 TCP/IP 套接字与数据库服务器进行通信。
TCP/IP 套接字
客户端应使用常规 TCP/IP 套接字连接数据库。
端口
mongod
和mongos
实例的默认端口号为 27017 。mongod
和 mongos
的端口号可配置,且可能不同。
字节排序
MongoDB 传输协议中的所有整数均采用小端字节顺序:即,最低有效字节在前。
消息类型和格式
MongoDB 将 OP_MSG 操作码同时用于客户端请求和数据库回复。旧版本的 MongoDB 采用多种消息格式,而这些格式现已弃用并替换为 OP_MSG
。
注意
该页面使用类似 C 语言的
struct
来描述消息结构。本文档中使用的类型(例如
int32
和cstring
)与BSON规范中定义的类型相同。为了表示重复,该文档使用 BSON 规范 中的星号表示法 。例如,
int64*
表示可以将一个或多个指定类型依次写入套接字。标准消息头的类型为
MsgHeader
。 整数常量为大写(例如ZERO
表示0的整数值)。
标准消息头
一般来说,每条消息均包含一个标准消息头,并后跟特定于请求的数据。标准消息头的结构如下:
struct MsgHeader { int32 messageLength; // total message size, including this int32 requestID; // identifier for this message int32 responseTo; // requestID from the original request // (used in responses from db) int32 opCode; // request type - see table below for details }
字段 | 说明 |
---|---|
| 消息的总大小(以字节为单位)。该总数包括保存消息长度的 4 个字节。 |
| 客户端或数据库生成的标识符,用于唯一标识此消息。对于客户端生成的消息(例如 OP_QUERY 和 OP_GET_MORE ),它将在 |
| 对于来自数据库的消息,这将是从来自客户端的 |
|
请求操作码
注意
从MongoDB 2.6和
maxWireVersion
3
开始, MongoDB驱动程序使用数据库命令insert
、update
和delete
而不是OP_INSERT
、OP_UPDATE
和OP_DELETE
进行确认写入。 大多数驱动程序继续使用操作码进行未确认的写入。在版本 4.2 中,MongoDB 删除了已弃用的内部
OP_COMMAND
和OP_COMMANDREPLY
协议。在版本5.0中, MongoDB 弃用了以下操作码:
OP_REPLY
OP_UPDATE
OP_INSERT
OP_QUERY
[1]OP_GET_MORE
OP_DELETE
OP_KILL_CURSORS
[1] MongoDB 5.0已弃用 OP_QUERY
查找操作和OP_QUERY
命令。 但有一例外:OP_QUERY
仍支持在连接握手过程中运行hello
和isMaster
命令。
MongoDB 支持这些opCode
值:
操作码名称 | 值 | Comment |
---|---|---|
| 2013 | 使用 MongoDB 3.6中引入的格式发送消息。 |
OP_REPLY Deprecated in MongoDB 5.0. | 1 | 回复客户端请求。 |
OP_UPDATE Deprecated in MongoDB 5.0. | 2001 年 | Update document. |
OP_INSERT Deprecated in MongoDB 5.0. | 2002 | 插入新文档。 |
| 2003 | 之前曾供 OP_GET_BY_OID 使用。 |
OP_QUERY Deprecated in MongoDB 5.0. | 2004 年 | 查询一个集合。 |
OP_GET_MORE Deprecated in MongoDB 5.0. | 2005 | 从查询中获取更多数据。参见游标。 |
OP_DELETE Deprecated in MongoDB 5.0. | 2006 | 删除文档。 |
OP_KILL_CURSORS Deprecated in MongoDB 5.0. | 2007 | 通知数据库该客户端已完成游标操作。 |
| 2012 | 使用压缩包装其他操作码 |
客户端请求消息
OP_MSG
OP_MSG
是一种可扩展消息格式,旨在包含其他操作码的功能。 该操作码的格式如下:
OP_MSG { MsgHeader header; // standard message header uint32 flagBits; // message flags Sections[] sections; // data sections optional<uint32> checksum; // optional CRC-32C checksum }
字段 | 说明 |
---|---|
| |
| |
| |
| 可选的 CRC-32 C校验和,如校验和中所述。 |
标记位
flagBits
整数是位掩码编码标志,用于修改 OP_MSG
的格式和行为。
前 16 位 (0-15) 必须进行设置;如果设置了未知位,解析器则必须报错。
最后 16 位 (16-31) 是可选的,解析器必须忽略任何未知的计算置位。代理和其他消息转发器必须在转发消息之前清除任何未知的可选位。
Bit | 名称 | 请求 | 响应 | 说明 |
---|---|---|---|---|
0 |
| ✓ | ✓ | 该消息以包含4 CRC-32 C [2 ]校验和的 字节结束。有关详细信息,请参阅校验和。 |
1 |
| ✓ | ✓ | 另一条消息将紧随其后,而接收者无需执行后续操作。接收者在收到 |
16 |
| ✓ | 客户端已准备好使用 此举可仅当请求者的网络层已为多个回复做好准备时才发送多个回复。 重要MongoDB 3.6会忽略此标志,并用一条消息进行响应。 |
部分
一条 OP_MSG
消息包含一个或多个部分。每个部分都以指示其类型的 kind
字节开头。kind
字节之后的所有内容构成该部分的有效负载。
可用的部分类型如下。
类型 0:正文
正文部分会编码为单个 BSON 对象。BSON 对象中的此大小也会用作该部分的大小。此部分类型为标准命令请求和回复正文。
所有顶级字段均须具有唯一名称。
第 1 类:文档序列
类型 | 说明 |
---|---|
int32 | 该部分的大小(以字节为单位)。 |
C 字符串 | 文档序列标识符。在所有当前命令中,该字段是它从正文部分替换的(可能是嵌套的)字段。 此字段不得同时存在于正文部分。 |
零个或多个 BSON 对象 |
|
校验和
每条消息均可能以 CRC-32C [2] 校验和结尾,而其中涵盖了消息中除校验和自身之外的所有字节。
从 MongoDB 4.2 开始:
如果显示带有校验和的消息,驱动程序和较旧的二进制文件将忽略校验和。
校验和的存在由 checksumPresent
标记位指示。
OP_UPDATE
已在MongoDB 5.0中弃用。
OP_UPDATE 消息用于更新集合中的文档。OP_UPDATE 消息的格式如下:
struct OP_UPDATE { MsgHeader header; // standard message header int32 ZERO; // 0 - reserved for future use cstring fullCollectionName; // "dbname.collectionname" int32 flags; // bit vector. see below document selector; // the query to select the document document update; // specification of the update to perform }
字段 | 说明 |
---|---|
| |
| 整数值 0。保留供将来使用。 |
| 完整的集合名称;即命名空间。 完整的集合名称是数据库名称与集合名称的串联,使用 |
| 用于指定操作标志的位向量。 位值对应如下内容:
|
| BSON 文档,指定选择要更新的文档的查询。 |
| BSON 文档,指定要执行的更新。有关指定更新的信息,请参阅更新操作文档。 |
对 OP_UPDATE 消息没有响应。
OP_INSERT
已在MongoDB 5.0中弃用。
OP_INSERT 消息用于将一个或多个文档插入到集合中。 OP_INSERT 消息的格式为
struct { MsgHeader header; // standard message header int32 flags; // bit vector - see below cstring fullCollectionName; // "dbname.collectionname" document* documents; // one or more documents to insert into the collection }
字段 | 说明 |
---|---|
| |
| 用于指定操作标志的位向量。 位值对应如下内容:
|
| 完整的集合名称;即命名空间。 完整的集合名称是数据库名称与集合名称的串联,使用 |
| 要插入集合的一个或多个文档。如果有多个文档,则按顺序依次写入套接字。 |
对 OP_INSERT 消息没有响应。
OP_QUERY
已在MongoDB 5.0中弃用。
OP_QUERY 消息用于在数据库中查询集合中的文档。OP_QUERY 消息的格式为:
struct OP_QUERY { MsgHeader header; // standard message header int32 flags; // bit vector of query options. See below for details. cstring fullCollectionName ; // "dbname.collectionname" int32 numberToSkip; // number of documents to skip int32 numberToReturn; // number of documents to return // in the first OP_REPLY batch document query; // query object. See below for details. [ document returnFieldsSelector; ] // Optional. Selector indicating the fields // to return. See below for details. }
字段 | 说明 | |
---|---|---|
| ||
| 用于指定操作标志的位向量。 位值对应如下内容:
| |
| 完整的集合名称;即命名空间。 完整的集合名称是数据库名称与集合名称的串联,使用 | |
| 设置返回查询结果时要忽略的文档数量(从结果数据集的第一个文档开始)。 | |
| 限制查询的第一条 OP_REPLY 消息中的文档数量。但是,如果结果多于 ,数据库仍会建立游标并将 | |
| 表示查询的 BSON 文档。 查询将包含一个或多个元素,所有这些元素都必须与要包含在结果集中的文档匹配。 可能的元素包括 | |
| 可选。用于限制已返回文档中的字段的 BSON 文档。
|
数据库将使用 OP_QUERY 消息来响应 OP_REPLY 消息。
OP_GET_MORE
已在MongoDB 5.0中弃用。
OP_GET_MORE 消息用于在数据库中查询集合的文档。OP_GET_MORE 消息的格式为:
struct { MsgHeader header; // standard message header int32 ZERO; // 0 - reserved for future use cstring fullCollectionName; // "dbname.collectionname" int32 numberToReturn; // number of documents to return int64 cursorID; // cursorID from the OP_REPLY }
字段 | 说明 |
---|---|
| |
| 整数值 0。保留供将来使用。 |
| 完整的集合名称;即命名空间。 完整的集合名称是数据库名称与集合名称的串联,使用 |
| 限制查询的第一条 OP_REPLY 消息中的文档数量。但是,如果结果多于 |
| OP_REPLY 中的游标标识符。这必须是来自数据库的值。 |
数据库将使用 OP_REPLY 消息来响应 OP_GET_MORE 消息。
OP_DELETE
已在MongoDB 5.0中弃用。
OP_DELETE 消息用于从集合中删除一个或多个文档。OP_DELETE 消息的格式为:
struct { MsgHeader header; // standard message header int32 ZERO; // 0 - reserved for future use cstring fullCollectionName; // "dbname.collectionname" int32 flags; // bit vector - see below for details. document selector; // query object. See below for details. }
字段 | 说明 |
---|---|
| |
| 整数值 0。保留供将来使用。 |
| 完整的集合名称;即命名空间。 完整的集合名称是数据库名称与集合名称的串联,使用 |
| 用于指定操作标志的位向量。 位值对应如下内容:
|
| BSON文档,表示用于选择要删除的文档的查询。 选择器将包含一个或多个元素,所有这些元素都必须与要从集合中删除的文档匹配。 |
对 OP_DELETE 消息没有响应。
OP_KILL_CURSORS
已在MongoDB 5.0中弃用。
OP_KILL_CURSORS 消息用于关闭数据库中的活动游标。这是必要的操作,用于确保在查询结束时回收数据库资源。OP_KILL_CURSORS 消息的格式为:
struct { MsgHeader header; // standard message header int32 ZERO; // 0 - reserved for future use int32 numberOfCursorIDs; // number of cursorIDs in message int64* cursorIDs; // sequence of cursorIDs to close }
字段 | 说明 |
---|---|
| |
| 整数值 0。保留供将来使用。 |
| 消息中的游标 ID 的数量。 |
| 要关闭的游标 ID 的“数组”。如果有多个操作码,则按顺序依次写入套接字。 |
如果读取游标直至耗尽(读取直至 OP_QUERY 或 OP_GET_MORE 返回游标 ID 为零),则无需终止游标。
OP_COMPRESSED
任何操作码都可以压缩并包装在 OP_COMPRESSED 标头中。 OP_COMPRESSED 消息包含原始压缩操作码消息以及处理和解压缩该消息所需的元数据。
OP_COMPRESSED 消息的格式为:
struct { MsgHeader header; // standard message header int32 originalOpcode; // value of wrapped opcode int32 uncompressedSize; // size of deflated compressedMessage, excluding MsgHeader uint8 compressorId; // ID of compressor that compressed message char *compressedMessage; // opcode itself, excluding MsgHeader }
字段 | 说明 |
---|---|
| |
| 包含封装操作码的值。 |
| 缩小后的 |
| 压缩此消息的压缩器的 ID。 |
| 操作码本身,不包括 |
为每个压缩器均分配了一个预定义的压缩器 ID,如下所示:
compressorId | 握手值 | 说明 |
---|---|---|
| noop | 此消息的内容未压缩。此举意在用于测试。 |
| snappy | 此消息的内容使用 snappy 进行压缩。 |
| zlib | 此消息的内容使用 zlib 进行压缩。 |
| zstd | 此消息的内容使用 zstd 进行压缩。 |
| reserved | 保留以供将来使用。 |
数据库响应消息
OP_REPLY
已在MongoDB 5.0中弃用。
OP_REPLY
消息由数据库发送,以响应 OP_QUERY 或 OP_GET_MORE 消息。OP_REPLY 消息的格式为:
struct { MsgHeader header; // standard message header int32 responseFlags; // bit vector - see details below int64 cursorID; // cursor id if client needs to do get more's int32 startingFrom; // where in the cursor this reply is starting int32 numberReturned; // number of documents in the reply document* documents; // documents }
字段 | 说明 |
---|---|
| |
| 用于指定标志的位向量。 位值对应如下内容:
|
|
|
| 游标的起始位置。 |
| 回复中的文档数量。 |
| 已返回文档。 |
脚注
[2] | 使用 Castagnoli 多项式计算出的 (1,2)32 位 CRC ,如 https://tools.ietf.org/html/rfc4960#page-140所述。 |