因此,我的map reduce操作将小额付款列表汇总为我欠特定用户的一次性付款。user_id最终成为_id。我还存储了一个需要支付的小额支付的数组id。产出进入一个叫做支付的永久性集合。
一个文档的输出如下
{ "_id" : ObjectId("4f48855606164f4765000004"), "value" : { "payment" : "5.0", "conversions" : [ ObjectId("4f5bd23baa113e964700000e") ] } }
我有点想跟踪这些付款,所以我想围绕收款建立一个mongoid文档。我知道这是可以做到的,但我还没有真正看到有人这样做,所以这让我觉得一定有更好的方法。
这种方法的一个问题是,我每个月都要付款,所以id和user_id会发生冲突。此外,我认为可能存在交易问题,因为我需要将小额支付更新到不同的状态,这样我就知道不再支付了,如果其中一次支付失败会发生什么?这些状态通过state_machine进行更改(如果有任何不同的话)。
我应该以Mongoid文档的形式访问Map Reduce输出吗?
当然你肯定能做到。这就是M/R输出到集合而不仅仅是"某个文件"的原因。
这种方法的一个问题是,我每个月都要付款,所以id和user_id会发生冲突。
很明显,M/R的输出是重要的数据。不要把这些数据留在一个可能会被未来M/R"锤击"的集合中。相反,可以重命名您创建的集合,或者运行for
循环,手动将数据附加到"keeper"集合。
在"keeper"集合中,将_id
更改为类似_id: { uid: ObjectId('...'), month: "201203" }
的内容。您可能还想将values
字段"扇出"为多个字段。您需要添加一个交易ID字段。
还要记住,MongoDB默认使用"fire&forget"写入。这些是低安全性的。您有财务数据,因此请确保您遵循可用性和数据安全方面的所有最佳实践:
- 日志记录打开
- 副本集(带辅助数据中心)
- 确保对该集合/db的所有写入都是使用
w: majority
和journal: true
完成的。这将降低此操作的DB吞吐量,因为这些写入可能需要几百毫秒 - 数据库密码
- 非标准MongoDB端口,IP白名单(通常的DB安全)
如果其中一笔付款失败,会发生什么?
这是一个不平凡的问题,太复杂了,无法在这里解释。相反,请参阅关于MongoDB的两阶段提交的文档。
请注意,两阶段提交需要MongoDB的findAndModify
命令。您必须学习如何使用Mongoid处理此问题。