如何使用 Mongo C 驱动程序插入带有空键的文档?

问题描述

我用 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" }

所以:

  1. 这是 C 驱动程序的限制,或者
  2. 我做错了 :)

你能帮我解决这个问题吗?谢谢!

关于我的系统的一些附加信息:

  • 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);