问题描述
我用 C 编写了这个程序(hello world example at Mongo C driver documentation 的一个轻微变体:
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
// file insert.c
// compiled with: gcc -o insert insert.c $(pkg-config --libs --cflags libmongoc-1.0)
int main (int argc,char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_oid_t oid;
bson_t *doc;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example");
collection = mongoc_client_get_collection (client,"mydb","mycoll");
doc = bson_new ();
bson_oid_init (&oid,NULL);
BSON_APPEND_OID (doc,"_id",&oid);
BSON_APPEND_UTF8 (doc,"","my_key_is_empty");
if (!mongoc_collection_insert_one (
collection,doc,NULL,&error)) {
fprintf (stderr,"%s\n",error.message);
}
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
重要的语句是这个,设置一个空的 BSON 密钥(有点奇怪但合法):
BSON_APPEND_UTF8 (doc,"my_key_is_empty");
如果我运行该程序,我会收到此错误:
invalid document for insert: empty key
这有点令人惊讶,因为如果我尝试用 Mongo shell 做同样的事情,它工作正常:
> db.mycoll.insert({"": "my_key_is_empty"})
WriteResult({ "nInserted" : 1 })
> db.mycoll.find()
{ "_id" : ObjectId("60182cb49fb197394497431e"),"" : "my_key_is_empty" }
所以:
- 这是 C 驱动程序的限制,或者
- 我做错了 :)
你能帮我解决这个问题吗?谢谢!
关于我的系统的一些附加信息:
- gcc 版本:6.3.0
- Mongo C 驱动版本:1.16.0
- MongoDB 版本:4.4.1
- 操作系统:Debian 9.3
解决方法
这似乎是一项功能。
您可以使用 BSON_VALIDATE_EMPTY_KEYS
libbson 选项来控制是否执行此验证。
这个版本的程序解决了这个问题:
include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
// file insert.c
// compiled with: gcc -o insert insert.c $(pkg-config --libs --cflags libmongoc-1.0)
int main (int argc,char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_oid_t oid;
bson_t *doc;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example");
collection = mongoc_client_get_collection (client,"mydb","mycoll");
doc = bson_new ();
bson_oid_init (&oid,NULL);
BSON_APPEND_OID (doc,"_id",&oid);
BSON_APPEND_UTF8 (doc,"","my_key_is_empty");
bson_t *opt = BCON_NEW("validate",BCON_BOOL(false));
if (!mongoc_collection_insert_one (
collection,doc,opt,NULL,&error)) {
fprintf (stderr,"%s\n",error.message);
}
bson_destroy (doc);
bson_destroy (opt);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
重要的部分是这个,关闭验证:
bson_t *opt = BCON_NEW("validate",&error)) {
...
}
...
bson_destroy (opt);