修改Mongodb源代码以禁用自动生成" _id" doc的字段

时间:2017-07-17 14:35:47

标签: c++ mongodb

我想修改和编译mongodb的最新源代码(截至目前,来自github的mongodb版本v3.5.10-34-g27d21e6),以使 _id 字段不会自动生成如果在插入文档时未提供,则生成。目前官方发布的mongodb需要存在这个字段(我已经在https://www.mongodb.org)的mongodb-win32-x86_64-v3.4-latest上测试了这个事实。

我找到了一个相关的问题Mongodb inserting doc without _id field。但是我认为我的问题与这个问题没有重复,因为我的问题是要求修改源代码,而这个问题与参数设置有关(其答案也不再适用于当前版本的mongodb)。

我知道官方mongodb集团有他们的理由和考虑需要这样一个 _id 字段,因为他们决定引入这样的要求,所以他们不太可能会删除它在不久的将来。而且我也知道禁用 _id 会影响mongodb的某些功能,例如上面提到的复制。但我仍然想知道如何禁用它,因为我只是将它用作在一台机器上只运行一个实例的个人数据库。我相信我不会需要其他功能。存储是我最考虑的,所以我不希望这个字段占用额外的磁盘空间。出于同样的原因,我需要具有压缩能力的wiredTiger引擎,所以我需要对相对较新版本的mongodb执行此操作。

截至目前,我已成功使用安装了VS2015的scons编译并链接了原始源代码v3.5.10-34-g27d21e6。所以我希望有人可以告诉我应该修改哪些代码段/哪些源代码文件/文件来禁用自动生成 _id 字段;哪些文件还需要修补"这将检查 _id 的存在,即使他们并不真的需要,也会拒绝正常工作。

以下两个文件是我发现的相似内容:

1)mongo / src / mongo / db / ops / insert.cpp line:153-177

我尝试按如下方式修改此文件,但之后仍然会自动创建 _id

从:

if (firstElementIsId) {
        b.append(doc.firstElement());
        i.next();
    } else {
        BSONElement e = doc["_id"];
        if (e.type()) {
            b.append(e);
        } else {
            b.appendOID("_id", NULL, true);
        }
    }

    while (i.more()) {
        BSONElement e = i.next();
        if (hadId && e.fieldNameStringData() == "_id") {
            // no-op
        } else if (e.type() == bsonTimestamp && e.timestampValue() == 0) {
            auto nextTime = LogicalClock::get(service)->reserveTicks(1);
            b.append(e.fieldName(), nextTime.asTimestamp());
        } else {
            b.append(e);
        }
    }

为:

if (firstElementIsId) {
        //b.append(doc.firstElement());
        i.next();
    } else {
        BSONElement e = doc["_id"];
        if (e.type()) {
            //b.append(e);
        } else {
            //b.appendOID("_id", NULL, true);
        }
    }

    while (i.more()) {
        BSONElement e = i.next();
        if (hadId && e.fieldNameStringData() == "_id") {
            // no-op
        } else if (e.fieldNameStringData() == "_id") {
            // no-op
        } else if (e.type() == bsonTimestamp && e.timestampValue() == 0) {
            auto nextTime = LogicalClock::get(service)->reserveTicks(1);
            b.append(e.fieldName(), nextTime.asTimestamp());
        } else {
            b.append(e);
        }
    }

2)mongo / src / mongo / bson / bsonobj.cpp行:281-315

我没有修改此文件,因为我没有看到哪行代码可能会添加 _id 字段,只是觉得它可能与其中提到的问题有关。它的评论。

/* note: addFields always adds _id even if not specified
   returns n added not counting _id unless requested.
*/
int BSONObj::addFields(BSONObj& from, set<string>& fields) {
    verify(isEmpty() && !isOwned()); /* partial implementation for now... */

    BSONObjBuilder b;

    int N = fields.size();
    int n = 0;
    BSONObjIterator i(from);
    bool gotId = false;
    while (i.moreWithEOO()) {
        BSONElement e = i.next();
        const char* fname = e.fieldName();
        if (fields.count(fname)) {
            b.append(e);
            ++n;
            gotId = gotId || strcmp(fname, "_id") == 0;
            if (n == N && gotId)
                break;
        } else if (strcmp(fname, "_id") == 0) {
            b.append(e);
            gotId = true;
            if (n == N && gotId)
                break;
        }
    }

    if (n) {
        *this = b.obj();
    }

    return n;
}

所以,这就是我现在所做的。 我不熟悉mongodb源代码结构,这对我来说真的是一个很大的项目。期待一个详细的待办事项列表,我可以遵循修改代码而不需要太多的知识,需要mongodb如何工作。但是,当然,任何其他类型的相关信息都是受欢迎的。提前谢谢。

2 个答案:

答案 0 :(得分:1)

在您发布的第3个代码段中,将bool gotId = false替换为bool gotId = true可能会使其按照您的意愿运行 - 但它也可能会破坏事物。

你提到你开始这是为了提高存储性能的原因 - 删除一个真正会产生相当大差异的字段?如果确实如此,我会感到惊讶。更有可能的是,你所希望的某些功能会破坏(也许现在不是,也许很长一段时间在你最不期望的地方)。

除了警告,你说你想要:

  

我可以遵循修改代码的详细待办事项列表

你不太可能找到熟悉MongoDB源码的人,他们可以告诉你它是否安全/不安全,以及如何在StackOverflow上删除这个字段 - 你更有可能通过试图获得响应联系开发团队,或至少为open source effort添加代码的人员。尽管如此,作为最后的警告,你甚至不会找到任何人,他们会花时间列出这些步骤。像这样的修改往往需要大量的时间来理解源代码 - 没有简单的解决方法。

答案 1 :(得分:1)

你现在想做的事情是行不通的。 _id本质上是主键,在代码的许多地方都假设_id字段存在(当然也是唯一的)。如果您不太熟悉主键的概念,请将其视为数据库中的唯一记录标识。没有识别==没有记录。

您正在寻求的具体好处是什么?您应该重新解释您的问题并询问人们如何实现这一目标。

祝你好运!