Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Indexing CQL选择大于对索引非键列的查询_Indexing_Cassandra - Fatal编程技术网

Indexing CQL选择大于对索引非键列的查询

Indexing CQL选择大于对索引非键列的查询,indexing,cassandra,Indexing,Cassandra,EDIT1:在原始问题之后添加了一个案例来描述问题 我想查询一个不属于我的键的列。如果我理解正确,我需要在该列上定义一个二级索引。但是,我希望使用一个大于条件(不仅仅是相等条件),这似乎仍然不受支持 我错过什么了吗? 你将如何解决这个问题 我想要的设置: Cassandra 1.1.6 CQL3 CREATE TABLE Table1( KeyA int, KeyB int, ValueA int,

EDIT1:在原始问题之后添加了一个案例来描述问题

我想查询一个不属于我的键的列。如果我理解正确,我需要在该列上定义一个二级索引。但是,我希望使用一个大于条件(不仅仅是相等条件),这似乎仍然不受支持

我错过什么了吗? 你将如何解决这个问题

我想要的设置:

Cassandra 1.1.6
CQL3

CREATE TABLE Table1(
             KeyA int,
             KeyB int,
             ValueA int,
             PRIMARY KEY (KeyA, KeyB)
           );

CREATE INDEX ON Table1 (ValueA);

SELECT * FROM Table1 WHERE ValueA > 3000;
由于Cassandra 1.1.6仍然不支持在具有复合键的ColumnFamilies上定义二级索引,因此我必须找到一个临时解决方案,删除其中一个键,但在非相等条件下仍然存在相同的问题

还有别的办法解决这个问题吗

谢谢你抽出时间

有关资料来源:


编辑1

这里有一个案例可以解释这个问题。正如rs atl所指出的,这可能是一个数据模型问题。假设我在stackoverflow上保留了一个包含所有用户的列族。对于每个用户,我都保存了一批统计数据(声誉、NumOfAnswers、NumofVoces……它们都是int)。我想查询这些统计数据以获得相关用户

CREATE TABLE UserStats(
             UserID int,
             Reputation int,
             NumOfAnswers int,
             .
             .
             .
             A lot of stats...
             .
             .
             .
             NumOfVotes int,
             PRIMARY KEY (UserID)
           );
现在我感兴趣的是基于这些统计数据对UserID进行切片。我希望所有用户拥有超过10K的声誉,我希望所有用户回答少于5个问题,等等


我希望这有帮助。再次感谢。

在Cassandra中,处理这种情况最灵活的方法可能是为每个统计设置一个单独的CF,将sentinel值作为键,并在列名中设置统计值,如下所示:

CF: StatName {
  Key: SomeSentinelValue {
    [Value]:[UserID] = ""
  }
}
假设您的状态为NumAnswers,用户ID为字符串:

CF: NumAnswers {
  Key: 0 {
    150:Joe = ""
    200:Bob = ""
    500:Sue = ""
  }
  Key: 1000 {
    1020:George = ""
    1300:Ringo = ""
    1300:Mary = ""
  }
}

因此,您可以看到,您的键本质上是一组值,这些值可以是数据所需的粗粒度或细粒度,而您的列是值+用户ID的组合。您现在可以为Cassandra提供一个已知键(或一组键),用于所需的粗粒度范围(相等),然后对列名的第一个组件执行范围查询。请注意,您不能将用户ID作为值写入,因为这将防止两个用户拥有相同的计数。

在CQL中,您可以在为所有列创建索引(即二级索引)后对其应用
WHERE
子句。否则,将出现以下错误:

Bad Request: No indexed columns present in by-columns clause with Equal operator
不幸的是,即使使用二级索引,由于以下原因,WHERE子句也要求CQL在二级索引上至少有一个EQ

Q:为什么总是需要至少进行一次EQ比较 次级指数?

答:关于二级指数的不等式总是存在的 在内存中完成,因此在另一个辅助索引上没有至少一个EQ 您将加载数据库中的每一行,其中包含大量 数据库不是一个好主意。因此,通过在一个 (辅助)索引,您希望限制需要读入的行集 内存达到可管理的大小。(虽然很明显,你仍然可以 这也会带来麻烦)

因此,基本上,如果除了EQ比较之外还有其他内容,它会加载所有“与查询匹配”的行,并检查它们是否匹配,一次一行。这在默认情况下是不允许的,因为它“可能会很慢。”(本质上,索引只用于索引“for equality”,而不用于任何其他内容,如<和>关系数据库上的哪些索引会)

需要注意的一点是,如果在二级索引上有多个非EQ条件,则还需要在查询中包含
ALLOW FILTERING
关键字,否则将得到

无法执行此查询,因为它可能涉及数据筛选,因此可能具有不可预测的性能。如果要在性能不可预测的情况下执行此查询,请使用“允许筛选”

一种简单的解决方法是在表中附加一个虚拟列,其中所有行在该列上都具有相同的值。因此,在本例中,您可以仅对所需的列执行范围查询。请务必意识到,NoSQL数据库上的此类查询可能会使系统运行缓慢/陷入困境


示例

cqlsh:demo> desc table table1;

CREATE TABLE table1 (
  keya int,
  keyb int,
  dummyvalue int,
  valuea int,
  PRIMARY KEY (keya, keyb)
) ....

cqlsh:demo> select * from Table1;

 keya | keyb | dummyvalue | valuea
------+------+------------+--------
    1 |    2 |          0 |      3
    4 |    5 |          0 |      6
    7 |    8 |          0 |      9
在ValueA和DummyValue上创建二级索引:

cqlsh:demo> create index table1_valuea on table1 (valuea);
cqlsh:demo> create index table1_valueb on table1 (dummyvalue);
使用
DummyValue=0
ValueA
执行范围查询:

cqlsh:demo> select * from table1 where dummyvalue = 0 and valuea > 5 allow filtering;

 keya | keyb | dummyvalue | valuea
------+------+------------+--------
    4 |    5 |          0 |      6
    7 |    8 |          0 |      9
主键(KeyA、KeyB) );

在表1(ValueA)上创建索引

从表1中选择*值A>3000

Cassandra方法是使用一些分区键,并始终使用该分区键,为
ValueA
可能的
主键((KeyA,KeyB,ValueA)
设置一个聚类列,然后像这样使用:


从表1中选择*,其中KeyA='xx'和ValueA>3000

您必须具有相等条件,这是正确的。有许多帖子讨论了这一问题的原因。如果您能发布实际问题,我很乐意帮助您创建正确的数据模型。正如前面多次提到但值得重复的那样,使用Cassandra,您必须对数据进行建模以回答您的问题。首先,感谢您同意提供帮助。我将编辑我的帖子,并描述一个适合这个问题的简单案例。如果你对我的完整模型设计感兴趣,你可以在这里找到它:这个问题的相关列系列是TestsData。你事先知道你需要哪些列和/或值的范围是什么,或者这些是动态的吗?@rs\u atl:我有大约20个统计数据。我必须能够对所有用户进行切分。(顺便说一句:当你说动态时,你是指列吗?我不期望有很多新的统计数据,这个列族是静态的)+1建议使用DummyValue。它似乎是唯一允许您查询动态添加的列(而不是EQ查询)的解决方案。我遇到的任何其他解决方案都需要重新建模数据,这不是现有数据的选项。另一方面,这是一个非常糟糕的解决方案。根据文档:“在一辆极低的车上创建一个索引