2013-07-18 23 views
0

基本上我有三个属性:partIdmeasurementDefvalue。 每个部分(partId)由特定类型(measurementDef)的多个度量(值)组成。卡桑德拉:如何模型列家族执行相交样查询

格式化为一棵树它会是这个样子:

-part 1 
    |- measurementDef 1 -> 15,86 
    |- measurementDef 2 -> 19,54 
-part 2 
    |- measurementDef 1 -> 21,21 
    |- measurementDef 3 -> 65,54 
    |- measurementDef 4 -> 12,54 
-part 3 
    ... 

现在我的问题是:我应该如何模型我的专栏的家人做这样的事情:

SELECT partId 
FROM <table> 
WHERE measurementDef = xxx AND value > 10 
INTERSECT 
SELECT partId 
FROM <table> 
WHERE measurementDef = yyy AND value < 50 

换句话说:我想查找所有零件,其度量值的度量值xxx高于10,而其度量值yyy的度量值低于50.

回答

1

AFAIK,没有建模方法来进行相交在单个查询中。我建议使用下表设计:

create table mdefparts(
    mdef int, 
    value float, 
    parts set<uuid>, 
    primary key(mdef, value) 
); 

然后使用查询:

select parts from mdefparts where mdef=XXX and value > 10; 
select parts from mdefparts where mdef=YYY and value < 50; 

然后加入第一个查询所有集合为一组(比如说,集1)。

将第二个查询中的所有集合加入到set2中。

然后只是相交set1和set2。

0

可能有其他选择。

如果阈值超过,您可以创建一个在插入过程中设置为1或0的“虚拟”列。然后,创建一个复合列索引,像这样:

CREATE TABLE mdefparts (
      part int, 
      name text, 
      val double, 
      time timeuuid, 
      exceeded boolean, 
      PRIMARY KEY ((part, name), exceeded, time) 
    ); 

这工作就像这样:

cqlsh:test> CREATE TABLE mdefparts (
      ... part int, 
      ... name text, 
      ... val double, 
      ... time timeuuid, 
      ... exceeded boolean, 
      ... PRIMARY KEY ((part, name), exceeded, time) 
      ...); 
    cqlsh:test> 
    cqlsh:test> insert into mdefparts (part, name, val, time, exceeded) values (0, 'y', 100, 37a5de5c-efb3-11e2-99d0-f23c91aec05e, true); 
    cqlsh:test> insert into mdefparts (part, name, val, time, exceeded) values (0, 'x', 100, 37a5de6c-efb3-11e2-99d0-f23c91aec05e, true); 
    cqlsh:test> insert into mdefparts (part, name, val, time, exceeded) values (0, 'y', 10, 37a5de7c-efb3-11e2-99d0-f23c91aec05e, false); 
    cqlsh:test> insert into mdefparts (part, name, val, time, exceeded) values (1, 'y', 1, 37a5de8c-efb3-11e2-99d0-f23c91aec05e, false); 
    cqlsh:test> select * from mdefparts; 

    part | name | exceeded | time         | val 
    ------+------+----------+--------------------------------------+----- 
     0 | y | False | 37a5de7c-efb3-11e2-99d0-f23c91aec05e | 10 
     0 | y |  True | 37a5de5c-efb3-11e2-99d0-f23c91aec05e | 100 
     1 | y | False | 37a5de8c-efb3-11e2-99d0-f23c91aec05e | 1 
     0 | x |  True | 37a5de6c-efb3-11e2-99d0-f23c91aec05e | 100 

    cqlsh:test> select * from mdefparts where name in ('x','y') and part = 0 and exceeded = true; 

    part | name | exceeded | time         | val 
    ------+------+----------+--------------------------------------+----- 
     0 | x |  True | 37a5de6c-efb3-11e2-99d0-f23c91aec05e | 100 
     0 | y |  True | 37a5de5c-efb3-11e2-99d0-f23c91aec05e | 100 

的核心思想是在这里在这里查询到列的家庭模式。我添加了timeuuid以允许随着时间的推移进行多次测量。

+0

有趣的解决方案,但这需要预先知道门槛。 –

+0

它需要在您的应用程序中定义,是的。 您可以通过添加“超出”表示val中记录的值范围的整数列来改善此问题。例如: 0:0-19 1:20-99 2:100-199 3:200-499 这样会更细致,您可以更轻松地检测到您感兴趣的某些值。只需在此栏中添加二级索引即可。希望有所帮助! – omnibear