Rails ActiveRecord - 数组属性的唯一性和查找

时间:2012-04-23 17:59:35

标签: ruby-on-rails activerecord serialization associations

早上好,

我有一个Rails模型,其中我正在序列化一系列信息。有两件事对我很重要:

  1. 我希望能够确保这是唯一的(即不能有两个具有相同阵列的模型)
  2. 我希望能够搜索此哈希的现有模型(使用find_or_create_by方法)。
  3. 该模型描述了“投资组合” - 即一组股票或债券。该阵列描述了投资组合中的证券以及权重。我还有第二个模型,它是一组投资组合(我们称之为“Portcollection”以保持简单)。一个集合有许多组合,一个组合可以在许多集合中。换句话说:

    class Portfolio
      serialize :weights
      has_and_belongs_to_many :portcollections
    
    class Portcollection
      has_and_belongs_to_many :portfolios
    

    当我生成“portcollection”时,我需要构建一堆投资组合,我以编程方式执行(实现并不重要)。建立投资组合是一项昂贵的操作,所以我试图首先检查一个投资组合的存在。我以为我可以通过find_or_create_by来做到这一点,但没有太多运气。这是我目前的解决方案:

    Class Portcollection
      before_save :build_portfolios
    
      def build_portfolios
        ……
        proposed_weights = ……
        yml =proposed_weights.to_yaml
        if port = Portfolio.find_by_weights(yml)
          self.portfolios << port
        else
          self.portfolios << Portfolio.create!(:weights => proposed_weights)
        end
        ……..
    end
    

    这确实有效,但速度很慢。我有一种感觉这是因为我每次运行时都会将内容转换为YAML,当我尝试检查现有的投资组合时(这可能会运行数百万次),而我正在搜索字符串,而不是整数。我确实在这个专栏上有一个索引。

    有更好的方法吗?我想到了一些想法:

    • 计算“weights”数组的MD5哈希值,并保存到数据库列。每次我想搜索一个数组时,我仍然需要计算这个哈希值,但我有一种直觉,认为这对数据库来说更容易索引&amp;搜索?
    • 努力从has_and_belongs_to_many转移到has_many =&gt;通过,并将数组信息存储为数据库列。这样我就可以尝试整理一个可以检查唯一性的数据库查询,而不需要任何YAML或序列化......

    即。类似的东西:

    class Portfolio
      has_many :portcollections, :through => security_weights
    
    class Portcollections
      has_many :portfolios, :through => security_weights
    
    SECURITY_WEIGHTS
    id     portfolio_id      portcollection_id     weight_of_GOOG  weight_of_APPLE ……
    1           14                   15                   0.4           0.3
    

    如果重要,“权重”数组将如下所示:

    [ [‘GOOG’, 0.4] , [‘AAPL’, 0.3] , [‘GE’, 0.3] ]
    

    任何帮助将不胜感激。请记住,我是一个非常业余的人 - 编程对我来说只是一个爱好!如果我正在做任何非常黑客或遗漏明显的事情,请原谅我。

    谢谢!

    更新1

    我已经对Rails 3.2“store”方法做了一些研究,但这似乎也不是答案......它只是将对象存储为JSON,这使我同样缺乏可搜索性

1 个答案:

答案 0 :(得分:2)

我认为在其自己的列中存储单独的哈希是有效执行此操作的唯一方法。您正在使用序列化或设计为不易搜索的键/值存储。

请确保在散列之前考虑对您的值进行排序,否则您可以使用相同的内容但不同的哈希值。