如果我尝试在 MongoDB 中插入一个以某个键开头的文档,$
则会收到一条错误消息:
> db.x.insert({"a": {"$b": "1"}})
2016-09-29T21:14:23.078+0200 E QUERY [thread1] Error: field names cannot start with $ [$b] :
...
(我有一个使用 Node.js 驱动程序的类似行为的观察者)
但是,运行以下 C++ 程序:
#include <cstdlib>
#include <iostream>
#include "mongo/client/dbclient.h" // for the driver
// compile with: g++ test.cpp -pthread -lmongoclient -lboost_thread -lboost_system -lboost_regex -o test
void run() {
mongo::DBClientConnection c;
c.connect("localhost");
mongo::BSONObj doc = BSON("a" << BSON("$b" << 1));
c.insert("test.x", doc);
}
int main() {
mongo::client::initialize();
try {
run();
} catch( const mongo::DBException &e ) {
std::cout << "caught " << e.what() << std::endl;
}
return EXIT_SUCCESS;
}
我可以插入它,如图find()
所示:
> db.x.find()
{ "_id" : ObjectId("57ed67fdbf3a716e16f6d102"), "a" : { "$b" : 1 } }
因此,C++ 驱动程序似乎能够“绕过” MongoDB 文档中描述的文档结构规则。这种行为有什么解释吗?它可能会以某种方式“破坏” MongoDB 数据库(我想这种限制是有充分理由的,并且数据库中的文档不尊重它可能是有问题的)
我观察到只有当密钥$
不在第一级时才会发生这种情况。例如,如果我使用
mongo::BSONObj doc = BSON("$b" << 1);
然后我得到一个一致的错误
caught OperationException: { index: 0, code: 2, errmsg: "Document can't have $ prefixed field names: $b", op: { _id: ObjectId('57ed6a015365c193cbbb3231'), $b: 1 } }
以防万一,我使用的是 MongoDB 3.2.0 和旧版 C++ 驱动程序 1.0.7