1

I'm building an API using Express and Monk that connects to a database where wrote are mainly handled by a Meteor application.

I know that Meteor uses its own algorithm to generate IDs. So when I do something like that:

id = "aczXLTjzjjn3PchX6" // this is an ID generated by Meteor (not a valid MongoID)

Users.findOne({ _id: id }, function(err, doc) {
    console.log(doc);
});

Monk outputs:

Argument passed in must be a single String of 12 bytes or a string of 24 hex characters.

This way, it seems very tricky to me to design a solid and reliable REST API. Thus, I have two questions:

  1. How can I handle the difference in my queries between ids generated by Meteor and valid MongoID()? Is there a simple way to get JSON results from a Meteor database?

  2. Will it be a problem to insert documents from the API which this time will have a valid MongoId()? I will end up with both type of ids in my database, seems very bad to me. :/

4

2 回答 2

2

As I said in here, in a similar issue you can just override the id converter part of monk:

var idConverter = Users.id; // Keep a reference in case...
Users.id = function (str) { return str; };

But don't expect monk to convert Ids automatically anymore.

How can I handle the difference in my queries between ids generated by Meteor and valid MongoID()? Is there a simple way to get JSON results from a Meteor database?

Nothing much you need to do. When it is a valid ObjectId(mongo db ids) and you got a string just convert it to Object id:

id = ObjectId(id);
User.find(id, ...)

Here's the implementation for monk id method(this.col.id is reference to 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;
};

Will it be a problem to insert documents from the API which this time will have a valid MongoId()? I will end up with both type of ids in my database, seems very bad to me. :/

It is bad. Though it won't cause much trouble(in my experience in nodejs) if you be careful. But not all the times you are careful(programmer errors happen a lot), but it's manageable. In static languages(like Java) this is a big NO, because a field can only one type(either string or ObjectId).

My suggestion is that don't use mongodb ObjectId at all and just use strings as ids. On inserts just give it string _id, so the driver won't give it ObjectId. Though you can stop the driver from doing so by overriding pkFactory, but it doesn't seem to be easy with monk.

One more thing is that monk is not actively maintained and it's just a thin layer on top of mongodb. In my experience if you have multiple collections and large/complex code base mongoose will be much better to use.

于 2014-09-17T15:56:33.817 回答
1

只是为了保持这个问题的更新。

文档中所述,Monk 自动将字符串转换为 OjbectID。为了在不使用 hacky 解决方案的情况下禁用此行为,您必须禁用该功能。为此,您只需在获取数据库时将 castIds 设置为 false。所以:

const Users = db.get('users', { castIds: false });

现在这将起作用:

Users.findOne({ _id: "aczXLTjzjjn3PchX6" }, function(err, doc) {
        console.log(doc);
});
于 2017-07-13T09:22:18.130 回答