gpt4 book ai didi

node.js - 在 MongoDB 键中使用 '.'(或其他特殊字符)的惯用方法是什么?

转载 作者:可可西里 更新时间:2023-11-01 10:49:34 25 4
gpt4 key购买 nike

我一直在玩弄 MongoDB 并想通过域名来键控项目。问题是使用特殊字符,如句点“。” for keys 中断 Mongo 并出现错误:

错误: key www.google.com 不能包含“.”

例如,我希望能够存储:

stupidObject = {
'www.google.com': {
'8.8.8.8': 'Other info',
'8.8.4.4': ['item1', 'item2', ... , 'itemN']
},
'www.othersite.com': {
'8.8.8.8': 'Other info',
'8.8.4.4': ['item1', 'item2', ... , 'itemN']
},
}

我见过的所有解决方案都是以下变体:在保存前更改 key 、使用 Unicode 表示、在保存前散列 key 。例如查看答案:MongoDB dot (.) in key name

所有这些解决方案都会导致它们自己的问题,并且难以维护代码。程序员有责任记住进行此过滤并始终如一地进行。这是一个糟糕的解决方案。

我虽然考虑过散列,但冲突是一种风险(这几乎不可能调试)并且再次将责任推给程序员。想象一下这些解决方案将对国际开发团队产生的影响。

我的问题很简单:在 MongoDB 中执行此操作的正确方法是什么?

我最终得到了一个自定义解决方案,我递归地(警钟!)导航结构并替换特殊字符。这是通过利用 pre('save') 和 post('find') Hook 在 Mongoose Schema 中完成的。

这意味着程序员不必关心他们使用 key 和他们保存的域名的特殊字符,数据库层透明地处理所有事情。这对我来说似乎是更好的解决方案。

但是...这需要一些困惑的代码来解决使用 hasOwnProperty 时 Mongoose 对象行为不当的问题以及首先运行“.toObject()”然后通过引用传递原始“this”指针的要求。

这个解决方案有效,但我认为一定有更好的方法!感激地接受关于正确方法的任何想法或指导!当您看到下面的代码时,您就会明白为什么我认为必须有更好的方法!

我应该提到我不想安装任何库或有其他依赖项来解决这个问题。

这是使用的代码示例:

// Recursive function to replace character||string in keys that may cause violations
// Same code can be used to reverse the change
//
var replaceStringInKeys = function (stringToReplace, newString, regExp, thisObj, thisPtr) {
for(property in thisObj) {
if (thisObj.hasOwnProperty(property)) {
if(property.indexOf(stringToReplace) > -1) {
// Replace the '.'s with URL escaped version. Delete old object.
var newproperty = property.replace(regExp, newString);
thisObj[newproperty] = thisObj[property];
thisPtr[newproperty] = thisPtr[property];
delete thisObj[property];
delete thisPtr[property];
// Pass the new property too
if (thisObj[newproperty].constructor === Object) {
thisObj[newproperty] = replaceStringInKeys(stringToReplace, newString, regExp, thisObj[newproperty], thisPtr[newproperty]);
thisPtr[newproperty] = thisObj[newproperty];
}
continue;
}
if (thisObj[property].constructor === Object) {
thisObj[property] = replaceStringInKeys(stringToReplace, newString, regExp, thisObj[property], thisPtr[property]);
thisPtr[property] = thisObj[property];
}
}
}
return thisObj;
};

testSchema.pre('save', function(next) {
// Calling '.toObject' allows for hasOwnProperty to work
var thisObj = this.toObject();
console.log('Pre save record...');
// Duplicate the this pointer as mongo is too shit to use hasOwnProperty properly
replaceStringInKeys('.', '[whateveryouwantinsteadofdot]', /\./g, thisObj, this);
next();
});

testSchema.post('find', function(results) {
console.log('post find record...');
// Undo the changes made by the pre-save hook
var i;
for(i = 0; i < results.length; i++) {
var thisObj = results[i].toObject();
replaceStringInKeys('[whateveryouwantinsteadofdot]', '.', /\[whateveryouwantinsteadofdot\]/g, thisObj, results[i]);
}
});

注意:请小心使用此解决方案(如果您足够疯狂),因为可能存在安全问题。例如,如果坏人知道您替换“.”与 %2E 他们可以强制使用例如

hxxp://www.vulnerablesitethatdoesntexist.com/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E %2E/%2E%2E/%2E%2E/%2E%2E/etc/密码

正确转义但会透明地转换为目录遍历类型字符串:
hxxp://www.vulnerablesitethatdoesntexist.com/../../../../../../../../../../../etc/passwd

最佳答案

您应该将文档的结构更改为无效,使用点作为键。我几年前遇到过同样的问题。

yourStupidObject = {
'www.google.com': [
{'ip': '8.8.8.8', more: 'Other info',
{'ip': '8.8.4.4', more: ['item1']}
]
}

关于node.js - 在 MongoDB 键中使用 '.'(或其他特殊字符)的惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43607645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com