用于复杂序列生成和存储的模式

时间:2013-06-26 13:19:12

标签: mongodb schema mongoose

我有一个带有客户表的数据库。这些客户是企业,我正在尝试设计一种灵活,可靠的方式,允许客户设计自己的自定义发票编号。

例如:

  • 客户A发票序列:A-1306-1234,其中“A-”是静态文本,1306是YYMM,1234是每月重置的序列
  • 客户B发票序列:123456 - 这是一个永远计算的序列
  • 客户C发票序列:13-123456 - 此序列为YY-然后序列运行一年并重置。

我正在尝试决定允许某些任意序列成为此数字的一部分的最灵活方式。我还需要原子地生成这个数字并根据各个元素强加的固有规则处理序列的重置,例如序列中的MM推断纯增量每个月重新启动,其中MMDD推断纯增量元素重新启动每个一天。

自定义类型是否正确?一组getter和setter以及静态,方法和验证器?是否已有此类功能的设计模式?

2 个答案:

答案 0 :(得分:1)

我必须解决与客户B类似的问题。 我的解决方案:我创建了一个用于存储序列的集合,并添加了这样的文档:

{
 "_id" : "PIN",
 "_class" : "com.alldata.genIII.bo.Sequence",
 "description" : "Sequence for PIN numbers. Used in all Account collections. ",
 "nextValue" : NumberLong(100001)

}

我使用_id指定将使用序列的Account集合中的字段。我是根据用户要求在100001开始的。

创建帐户时,我获取序列的下一个值并更新添加1的序列。 此操作是原子操作,因为我使用findAndModify

这是我的代码(在java中)来获取序列的下一个值:

    public Long fetchNextValue(String sequenceId) {
        Update update = new Update();
        update.inc("nextValue", 1);
        Sequence seq = mongoTemplate.findAndModify(new Query(Criteria.where("code").is(sequenceId)), update, Sequence.class);
        if (seq == null)
            throw new NotFoundException("Sequence not found for sequenceId " + sequenceId);
        return seq.getNextValue();
    }

我在生产中运行此代码,到目前为止我没有遇到任何问题。但是为了以防万一,我在帐户集合的“pin”字段中放置了一个唯一索引,所以如果有重复,我会抓住异常并使用新引脚重试几次。

有关如何完成此操作的详细信息,请查看此article

对于其他情况,您可以使用存储在mongoDB中的javascript函数将该逻辑应用于序列。看看这个article,虽然现在有一条消息说他们不推荐它(这条消息是新的......)但它可以给你更多的想法。

希望这有帮助

答案 1 :(得分:0)

我已经完成了我的目标,其解决方案比我要找到的解决方案简单得多。在每个机构记录中,我创建了一个名为invoice_format的字符串字段。在此字段中,我存储了一个我解析的格式字符串以生成发票号。例如:

invoice_format: "A-{YY}{seq-04.d}"

我解析了这个,{}内的任何内容都被视为格式规则,{}之外的任何内容都被视为文字文本。我有一个不那么迷人的开关,它查找每个格式规则并根据规则返回一个值。我还有工作要做,但这构成了我的序列生成器的基础。每个客户的序列都保存在一个名为invoice_sequence的单独字段中,当我在字段中遇到{seq}时,我会增加该字段并返回结果。