如何在流星上创建自动增量字段?

Posted

技术标签:

【中文标题】如何在流星上创建自动增量字段?【英文标题】:How can I create an auto increment field on meteor? 【发布时间】:2013-03-30 23:47:36 【问题描述】:

我需要一个自动递增字段,但不是用于主 ID,它只是为客户支持应用程序的用户提供一个易于记忆的案例编号。

我发现这篇文章解释了如何在 mongodb http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/ 上创建自动增量字段,但 minimongo 尚不支持此解决方案。

如何实现此功能?我不在乎解决方案是否由于错误而跳过了一些连续的案例编号,但案例编号必须是唯一的。

是否有另一种方法可以生成唯一且简短的案例编号?我不想给用户一个像 PxyooJWSKc3sMz6Lc 这样的案例代码,因为他们必须参考案例编号的问题。

编辑:

Minimong 不支持 findAndModify,所以我不能使用我发布的链接中列出的第一个解决方案。第二种解决方案还需要 minimongo 上没有的方法。

【问题讨论】:

不幸的是,这是最安全的解决方案。 (Minimongo 好像不再更新了?您可能需要考虑使用 10gen 的 Python 官方驱动程序 PyMongo:api.mongodb.org/python/current)。 我编辑了我的问题。我认为使用最安全的解决方案,您可以参考我发布的链接,但它不适用于 minimongo,所以我还没有解决方案。 Meteor 是一个 node.js 框架,我没有使用 python。 对不起,minimongo 是/是一个最先出现的 python 库。 :) 所以,我以为你在说 Python。 【参考方案1】:

使用mongo-counter package,可以使用incrementCounter(name) 方法创建增量器。该实现基于Create an Auto-Incrementing Sequence Field 直接访问数据库而不通过 Meteor Collection。

Meteor.methods(
    'addRecord':function(doc) 
        doc.id = incrementCounter('docId');
        MyCollection.insert(doc);
        return doc.id;
    
);

更新

Atmosphere 上有new mongo counter packages,可能比我最初推荐的要好。

【讨论】:

请注意,不鼓励仅链接的答案,因此答案应该是搜索解决方案的终点(相对于另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。 应该安装哪个包?目前在大气 js.com 上有三个可用,它们之间没有明显区别:konecty:mongo-counter(最受欢迎)、mrt:mongo-counter(来自 awwx)和 gabrielengel:konecty-mongo-counter。 @10basetom,atmospherejs.com/?q=mongo-counter。我现在正在使用 osv:mongo-counter,但我建议您检查所有软件包(文档、使用统计、支持等)并选择更方便的。【参考方案2】:

嗯,有几种方法可以做到这一点。如果您需要它绝对一致,您可以将当前整数存储在您的集合中并使用 Meteor.call 添加新记录,而不是从客户端执行。

例如

服务器端js

Meteor.methods(
    'addRecord':function(doc) 
        currentId = MyCollection.findOne(,sort:id:-1).id || 1;
        doc.id = currentId + 1;
        MyCollection.insert(doc);
        return doc.id;
    
);

客户端js

doc = name:"Bob"
//MyCollection.insert(doc)

//Use this instead
Meteor.call("addRecord", doc, function(err,result) 
    if(result) 
        console.log("Successfully added new record with auto_inc id " + result);
    

使用 Meteor.call 执行此操作会丢失一件事:延迟补偿。

其他可能性

您可以存储从 Unix 时间戳构建的内容并将其缩短为更适用的内容(例如,通过截去前几位数字):

new Date().getTime().toString().substr(4)

【讨论】:

在这种情况下,我可以在没有延迟补偿的情况下生活,但是使用您的第一个解决方案,我认为 id 可以重复,因为操作不是原子的。我现在可以使用这个解决方案,因为我的用户很少,但是对于我要构建的另一个应用程序,我需要另一个解决方案。谢谢 我不太确定我能理解它在哪里是非原子的? Mongodb 并不是真正的酸兼容。对于节点,一次只能运行一个线程,因此如果不是更好,它应该与 MyCollection.insert 一样工作,因为以延迟补偿为代价返回实际的真/假回调 Mongodb 文档说“findAndModify() 方法以原子方式修改并返回单个文档。”它用于我发布的链接上的第一个解决方案,因此可以保证当我获得一个 id 时,它是唯一的。使用您的解决方案,我认为两个并发请求可以在插入之前获得相同的 id。我不是 mongodb 或 node.js 专家,所以我不确定我说的是不是真的。 如果node只运行一个线程,我想你是对的,唯一性会得到保证。 好的,我认为这需要更多解释,即使对我来说,我也不确定它是否是单线程的。我读过很多材料,说它在某个层次上,而不是在另一个层次上。它的事件,所以每个请求都会从主线程产生到一个节点工作者,这是单线程的,所以它们的唯一性仍然应该得到保证

以上是关于如何在流星上创建自动增量字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有自动增量的情况下创建主键?

如何在使用存储过程时创建具有自动增量的 id 字段?

如何将自动增量设置为非主键?

如何在休眠中映射自动增量字段?

如何使用自动增量更新字段 CONCAT?

如何在选择查询中生成自动增量字段