Express Mongoose和ref-UUID的数组';s不能转换
当使用库mongoose uuid时,我能够为我的模式设置uuid类型,因此当我读取数据时,它是字符串(utf-8)格式,当我保存数据时,它是uuid ObjectID BSON type 4格式。这对于我的模式中的顶级或平面直接值和ref定义非常有效。但是,当我在模式中的ref数组中有一个UUID时,数组会正确地保存到数据库中,但是当它呈现时,它是原始类型的。根据下面的示例,您可以看到scope_id以正确的格式显示,但权利不正确 以下是我正在使用的版本: 猫鼬uuid-2.3.0 猫鼬-5.5.11 我已经尝试通过更改getter和转换值来修改库(mongoose uuid),但是,当我这样做时,它在呈现时工作,但在保存到数据库时失败。这很可能是由于值在保存到数据库之前已转换或强制转换 下面是一个示例模式Express Mongoose和ref-UUID的数组';s不能转换,express,mongoose,uuid,mongoose-schema,Express,Mongoose,Uuid,Mongoose Schema,当使用库mongoose uuid时,我能够为我的模式设置uuid类型,因此当我读取数据时,它是字符串(utf-8)格式,当我保存数据时,它是uuid ObjectID BSON type 4格式。这对于我的模式中的顶级或平面直接值和ref定义非常有效。但是,当我在模式中的ref数组中有一个UUID时,数组会正确地保存到数据库中,但是当它呈现时,它是原始类型的。根据下面的示例,您可以看到scope_id以正确的格式显示,但权利不正确 以下是我正在使用的版本: 猫鼬uuid-2.3.0 猫鼬-5.
{
"code": {
"type": String,
"required": true
},
"scope_id": {
"type": mongoose.Types.UUID,
"ref": "scopes"
},
"entitlements": [{
"type": mongoose.Types.UUID,
"ref": "entitlements"
}]
}
实际响应示例
{
"entitlements": [
"zMihi1BKRomM1Q41p7hgLA==",
"ztOYL7n1RoGA6aoc0TcqoQ=="
],
"code": "APPUSR",
"scope_id": "b8f80c82-8325-4ffd-bfd7-e373a90e7c45",
"id": "32e79061-e531-45ad-b934-56811e2ad713"
}
预期反应
{
"entitlements": [
"ccc8a18b-504a-4689-8cd5-0e35a7b8602c",
"ced3982f-b9f5-4681-80e9-aa1cd1372aa1"
],
"code": "APPUSR",
"scope_id": "b8f80c82-8325-4ffd-bfd7-e373a90e7c45",
"id": "32e79061-e531-45ad-b934-56811e2ad713"
}
根据我的观察,如果您在mongoose中更改下面的函数,它可以正常工作
SchemaUUID.prototype.cast = function (value, doc, init) {
console.log("cast", value, doc, init)
if (value instanceof mongoose.Types.Buffer.Binary) {
if (init) {
return getter(value);
} else {
return value;
}
}
if (typeof value === 'string') {
var uuidBuffer = new mongoose.Types.Buffer(uuidParse.parse(value));
uuidBuffer.subtype(bson.Binary.SUBTYPE_UUID);
return uuidBuffer.toObject();
}
throw new Error('Could not cast ' + value + ' to UUID.');
};
基本上,当您保存对象时,
init
为false
,当其启动的init
为true
时,如上所述,代码确实工作,但会破坏代码的另一部分。我找到了一个解决方案来纠正这个问题:
这是对上述守则的轻微修订
SchemaUUID.prototype.cast = function (value, doc, init) {
console.log("cast", value, doc, init)
if (value instanceof mongoose.Types.Buffer.Binary) {
if (init && doc instanceof mongoose.Types.Embedded) {
return getter(value);
}
return value;
}
if (typeof value === 'string') {
var uuidBuffer = new mongoose.Types.Buffer(uuidParse.parse(value));
uuidBuffer.subtype(bson.Binary.SUBTYPE_UUID);
return uuidBuffer.toObject();
}
throw new Error('Could not cast ' + value + ' to UUID.');
};
此代码的替代版本允许应用POST和PATCH等更新 您可以尝试mongoose-uuid2包-它可能会解决这个问题,第一个版本不太流行
mongoose-uuid2
将ID存储为字符串,而mongoose uuid
将它们存储为二进制。二进制格式是性能所必需的,但也与文章中提到的问题有关。@jneander是正确的,mongoose uuid用于性能和存储问题。“mongoose-uuid2”在这种情况下没有帮助。我想我们是倒退了mongoose-uuid2
使用二进制,而mongoose-uuid
使用字符串。不过,结果是一样的。我从这个问题中得到了一些下游信息,并创建了猫鼬回购协议。似乎mongoose内部的某个地方缺少了一个部分。如果没有使用mongoose
的解决方案,我会直接使用官方的mongodb
节点驱动程序。在紧急情况下,您可以绕过mongoose
,处理它无法正确执行的任何查询。用mongoose
的方法规范化数据确实需要额外的工作。我尝试应用这种方法,但得到了相同的结果。我测试了它,然后只共享了,事实上,通过进一步的测试,我发现了问题,这是我这边的问题。您是对的,您的解决方案解决了问题。我在前面的评论中犯了错误******在附加说明中,通过更多的测试,这确实解决了问题,但现在破坏了我的补丁操作。我可以看到它通过init保存id并失败。如果你对此有一个建议,它会有所帮助。如果我必须的话,我会再发一个帖子。我建议你再发一个帖子,因为这会是另一个问题。由于某种原因,这对我来说并不起作用。doc不是嵌入的实例。它最终还是返回二进制文件。