是否有Ruby的数据库或数据结构来实现关系矩阵? [英] Is there a database or a data structure for Ruby to implement relation matrices?
问题描述
我有一个非常简单的资料集
I've got a very simple data set
- 产品
- 属性
-
交叉表:产品的属性相关性
- products
- attributes
cross table: attributes relevance for a product
red blue modern old fashion (50+ Entries)
Jeans myway 0% 100% 30% 30%
Polo Shirt 100% 0% 10% 40%
(500+ Entries)
在应用程序中选择红色,蓝色等属性,按照相关性排序。
In the application you select the attribute like red, blue, .. and get the the products sorted by relevance.
存储数据的最佳方法是什么,ruby有好的数据结构(库)?
What's the best way to store the data, is there a good data structure (library) for ruby?
(不要告诉我如何使用传统的3个表sql和活动记录实现它。我已经知道如何,我正在寻找一个更好的解决方案。)
(Don't tell me how to implement it with traditional 3 tables sql and active record. I already know how. I'm looking for a better solution.)
一种方法是使用哈希:
"red" => {"Jeans myway" => 0, "Polo Shirt" => 100}, "blue" => {..
这是一个很好的方法,我应该如何存储到文件?
is this a good way and how should I store it to file?
更好的解决方案:如果我采用关系数据库,我必须将矩阵分成3个表产品,属性,attributes_products。我想把它存储在一个表/矩阵,并搜索/使用它像一个矩阵。
[edit] Better solution: If I take a relational db, I've to split the matrix into 3 tables products, attributes, attributes_products. I would like to store it in one table / matrix and search / use it like a matrix.
例如。我想选择其中属性旧时尚,现代与相关性相关(> 0)的产品将返回Jeans myway 0.09,Polo Shirt 0.04。 (相关性通过乘法计算。)
E.g. I want to select products where the attributes 'old fashion', 'modern' are relevant (>0) sorted by relevance would return 'Jeans myway 0.09', 'Polo Shirt 0.04'. (Relevance is calculated by multiplication.)
推荐答案
这里有一个针对您的需求定制的解决方案。它允许您选择任意数量的产品或属性,并按照权重的乘积查看另一轴中的值。
Here's a solution tailored for your needs. It allows you to select an arbitrary number of products or attributes and see the values in the other axis sorted by the product of the weightings. It lets you store your data in CSV, so you can just keep a big Excel file of your grid for future tweaking.
merge_by
The merge_by
, sort_by
, and filter_by
methods let you specify the block to be applied when getting your results.
TESTDATA = <<ENDCSV
,red,blue,modern,old fashion,sexy
Jeans myway,0%,100%,30%,30%,70%
Polo Shirt,100%,0%,10%,40%,1%
Bra,100%,0%,100%,0%,100%
ENDCSV
def test
products = RelationTable.load_from_csv( TESTDATA )
p products.find( :col, 'old fashion','modern' )
#=> [["Jeans myway", 9.0], ["Polo Shirt", 4.0]]
p products.find( :row, 'Polo Shirt' )
#=> [["red", 100.0], ["old fashion", 40.0], ["modern", 10.0]]
p products.find( :col, 'sexy' )
#=> [["Bra", 100.0], ["Jeans myway", 70.0], ["Polo Shirt", 1.0]]
p products.find( :row, 'Polo Shirt','Bra' )
#=> [["red", 100.0], ["modern", 10.0]]
p products.find( :col, 'sexy','modern' )
#=> [["Bra", 100.0], ["Jeans myway", 21.0], ["Polo Shirt", 0.1]]
p products.find( :col, 'red', 'blue' )
#=> []
p products.find( :col, 'bogus' )
#=> []
end
class RelationTable
def self.load_from_csv( csv )
require 'csv'
data = CSV.parse(csv)
self.new( data.shift[1..-1], data.map{ |r| r.shift }, data )
end
def initialize( col_names=[], row_names=[], weights=[] )
@by_col = Hash.new{|h,k|h[k]=Hash.new(0)}
@by_row = Hash.new{|h,k|h[k]=Hash.new(0)}
row_names.each_with_index do |row,r|
col_names.each_with_index do |col,c|
@by_col[col][row] = @by_row[row][col] = weights[r][c].to_f
end
end
# Multiply all weights, sort by weight (descending), only include non-zero
merge_by{ |values| values.inject(1.0){ |weight,v| weight*v/100 }*100 }
sort_by{ |key,value| [-value,key] }
filter_by{ |key,value| value > 0 }
end
def merge_by(&proc); @merge = proc; end
def sort_by(&proc); @sort = proc; end
def filter_by(&proc); @filter = proc; end
def find( row_or_col, *names )
axis = (row_or_col == :row) ? @by_row : @by_col
merge(axis.values_at(*names)).select(&@filter).sort_by(&@sort)
end
private
# Turn an array of hashes into a hash of arrays of values,
# and then merge the values using the merge_by proc
def merge( hashes )
if hashes.length==1
hashes.first # Speed optimization; ignores the merge_by block
else
result = Hash.new{|h,k|h[k]=[]}
hashes.each{ |h| h.each{ |k,v| result[k] << v } }
result.each{ |k,values| result[k] = @merge[values] }
result
end
end
end
test if __FILE__==$0
这篇关于是否有Ruby的数据库或数据结构来实现关系矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!