我想修改和编译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如何工作。但是,当然,任何其他类型的相关信息都是受欢迎的。提前谢谢。
答案 0 :(得分:1)
在您发布的第3个代码段中,将bool gotId = false
替换为bool gotId = true
可能会使其按照您的意愿运行 - 但它也可能会破坏事物。
你提到你开始这是为了提高存储性能的原因 - 删除一个真正会产生相当大差异的字段?如果确实如此,我会感到惊讶。更有可能的是,你做所希望的某些功能会破坏(也许现在不是,也许很长一段时间在你最不期望的地方)。
除了警告,你说你想要:
我可以遵循修改代码的详细待办事项列表
你不太可能找到熟悉MongoDB源码的人,他们可以告诉你它是否安全/不安全,以及如何在StackOverflow上删除这个字段 - 你更有可能通过试图获得响应联系开发团队,或至少为open source effort添加代码的人员。尽管如此,作为最后的警告,你甚至不会找到任何人,他们会花时间列出这些步骤。像这样的修改往往需要大量的时间来理解源代码 - 没有简单的解决方法。
答案 1 :(得分:1)
你现在想做的事情是行不通的。 _id本质上是主键,在代码的许多地方都假设_id字段存在(当然也是唯一的)。如果您不太熟悉主键的概念,请将其视为数据库中的唯一记录标识。没有识别==没有记录。
您正在寻求的具体好处是什么?您应该重新解释您的问题并询问人们如何实现这一目标。
祝你好运!