我使用Express和Monk构建一个API,它连接到一个主要由Meteor应用程序处理的数据库。
我知道Meteor使用自己的算法来生成ID。所以当我做那样的事情时:
id = "aczXLTjzjjn3PchX6" // this is an ID generated by Meteor (not a valid MongoID)
Users.findOne({ _id: id }, function(err, doc) {
console.log(doc);
});
和尚输出:
Argument passed in must be a single String of 12 bytes or a string of 24 hex characters.
这样,设计一个可靠而可靠的REST API对我来说似乎非常棘手。因此,我有两个问题:
如何处理Meteor生成的ID与有效MongoID()之间的查询差异?有没有一种简单的方法可以从Meteor数据库中获取JSON结果?
从API中插入文件会有问题,这次会有一个有效的MongoId()吗?我最终会在我的数据库中使用这两种类型的ID,对我来说似乎非常糟糕。 :/
答案 0 :(得分:2)
正如我在here, in a similar issue中所说,你可以覆盖monk的id转换器部分:
var idConverter = Users.id; // Keep a reference in case...
Users.id = function (str) { return str; };
但是不要让僧侣自动转换ID。
如何处理Meteor生成的ID与有效MongoID()之间的查询差异?有没有一种简单的方法可以从Meteor数据库中获取JSON结果?
你无需做什么。当它是一个有效的ObjectId(mongo db ids)并且你得到一个字符串时只需将其转换为Object id:
id = ObjectId(id);
User.find(id, ...)
这里是monk id方法的实现(this.col.id是对mongodb native ObjectId的引用):
Collection.prototype.id =
Collection.prototype.oid = function (str) {
if (null == str) return this.col.id();
return 'string' == typeof str ? this.col.id(str) : str;
};
从API中插入文件会有问题,这次会有一个有效的MongoId()吗?我最终会在我的数据库中使用这两种类型的ID,对我来说似乎非常糟糕。 :/
很糟糕。如果你小心的话,它不会造成很多麻烦(根据我在nodejs的经验)。但并不是所有时候你都小心(程序员错误发生了很多),但它是可管理的。在静态语言(如Java)中,这是一个很大的NO,因为一个字段只能有一种类型(字符串或ObjectId)。
我的建议是,根本不使用mongodb ObjectId,只使用字符串作为ID。在插入上只给它字符串_id,所以驱动程序不会给它ObjectId。虽然你可以通过覆盖pkFactory来阻止驱动程序这样做,但是对于和尚来说这似乎并不容易。
还有一件事是,僧侣没有得到积极维护,而且只是在mongodb上面的一层薄层。根据我的经验,如果你有多个集合和大/复杂的代码库mongoose将更好用。
答案 1 :(得分:1)
只是为了更新此问题。
如docs所述,Monk会自动将字符串转换为OjbectID。 为了在不使用hacky解决方案的情况下禁用此行为,您必须禁用该功能。为了做到这一点,你只需要在获取数据库时将castIds设置为false。 所以:
const Users = db.get('users', { castIds: false });
现在这将有效:
Users.findOne({ _id: "aczXLTjzjjn3PchX6" }, function(err, doc) {
console.log(doc);
});