【问题标题】:Cassandra 1.1 composite keys, columns, and filtering in CQL 3CQL 3 中的 Cassandra 1.1 复合键、列和过滤
【发布时间】:2012-08-31 03:23:17
【问题描述】:

我希望有一个如下表:

CREATE TABLE ProductFamilies (
  ID varchar,
  PriceLow int,
  PriceHigh int,
  MassLow int,
  MassHigh int,
  MnfGeo int,
  MnfID bigint,
  Data varchar,
  PRIMARY KEY (ID)
);

总共有 13 个字段。其中大多数代表存储桶。数据是产品系列 ID 的 JSON,然后在后续查询中使用。 鉴于 Cassandra 的工作方式,引擎盖下的列名将是值。我希望过滤这些。

我希望按如下方式运行查询:

SELECT Data FROM MyApp.ProductFamilies WHERE ID IN (?, ?, ?) AND PriceLow >= ? 
AND PriceHigh <= ? AND MassLow >= ? AND MassHigh <= ? and MnfGeo >= ? AND 
MnfGeo <= ?
  1. 我读到 Cassandra 只能针对复合行键或索引列执行 WHERE 谓词。这仍然是真的吗?如果是这样,我将不得不使列
  2. 是否仍然需要从左到右包含所有列并且不能跳过任何列?
  3. 我的设计中是否存在任何非最佳点?
  4. 我想添加一列“材料”,它是产品系列中可能材料的数组。想想披萨配料,并查询“WHERE Materials IN ('Pineapple')”。如果不创建单独的材料倒排索引,然后对上述查询执行手动交集,在 Cassandra 中是否还有其他 [更优雅的] 方法来处理这个问题?

【问题讨论】:

  • 再一次这是我的答案,它仍然适用:D stackoverflow.com/questions/11825783/…
  • 是的...谢谢,但是只能针对 PK 进行过滤有什么意义呢?我知道你的回答是对的 ;)
  • “根据你的阅读模式建模你的数据”是 cassandra 的经验法则。上述原因的唯一原因是您无法进行连接,您无法过滤列值,直到您索引一个:) 所以,请提及您的完整用例和阅读模式以帮助我们:P
  • 我想我确实提到了我的用例:P...让我扩展这个问题。
  • 我的数据是按照我的阅读模式建模的。根据您的上一个。答案,我相信我有这个正确的。据我了解,CQL 3 会将值存储为列名,不包括最终数据值。

标签: indexing cassandra database-indexes


【解决方案1】:

如果您指定要查找的确切 PK,正如您在此处建议的那样(id IN ...),您可以在其余谓词中使用您喜欢的任何表达式。没有限制。

从计划于 10 月底发布的 1.2.0 开始支持列表集合。可能支持也可能不支持集合内容的索引查询。

【讨论】:

  • 我看到一封来自您的电子邮件,指出 #1(WHERE 必须针对 PK 组件)。所以这有定义。变了吗?
  • 列表集合是否支持推送和弹出?
  • @jbellis 如果你能验证我的回答,那就太好了:)
  • 而且,这是否意味着只要指定了 PK,WHERE 子句就可以在 schmeless 设计中使用(实际上,我没有得到 PK 和 can-use-WHERE 之间的联系)。
  • @jbellis 请看这个问题:stackoverflow.com/questions/12609008/…
【解决方案2】:

基本上是为了支持您需要的查询

create column family ProductFamilies with 
comparator='CompositeType(UTF8Type, Int32Type, Int32Type, Int32Type, Int32Type, Int32Type, LongType, UTF8Type)' 
and key_validation_class='UTF8Type'

CREATE TABLE ProductFamilies (
  ID varchar,
  PriceLow int,
  PriceHigh int,
  MassLow int,
  MassHigh int,
  MnfGeo int,
  MnfID bigint,
  Data varchar,
  PRIMARY KEY (ID, PriceLow, PriceHigh, MassLow, MnfGeo, MnfID, Data)
);

现在可以查询了

SELECT Data FROM MyApp.ProductFamilies WHERE ID IN (?, ?, ?) AND PriceLow >= ? 
AND PriceHigh <= ? AND MassLow >= ? AND MassHigh <= ? and MnfGeo >= ? AND 
MnfGeo <= ?

如果您没有从左到右错过任何列 [虽然不是过滤器,但至少有一个 *],并且您的所有值都在列名中而不是值中。

关于复合列,您应该了解的另一件事是“列切片必须是连续的”因此,pricelow > =10 和 pricelow =10 [tested with phpcassa] 因为它会再次产生一个连续的切片。

否则,在您的任何列上创建一个或多个二级索引。然后,您有权根据列值进行查询,前提是您在查询中始终具有至少一个索引字段。 http://www.datastax.com/docs/1.1/ddl/indexes

关于你的实质性问题,据我所知,如果它是一个多值列,那么除了倒排索引之外别无他法。

如果@jbellis 验证这一点,那就太好了

【讨论】:

  • 为什么要写“PRIMARY KEY (ID, PriceLow, PriceHigh, MassLow, MnfGeo, MnfID, Data)”?至少,数据肯定是最终价值吗? @jbellis 似乎表明不再需要在 PK 中包含所有查询的列。
  • @IanC 我希望如果我正确理解复合列的推文示例datastax.com/docs/1.1/ddl/column_family#composite-columns 那么我提到的内容应该对你有用
  • 它会起作用的,是的。我只是觉得新版本放宽了之前的一些要求。
  • 我终于试过了。请看这个问题:stackoverflow.com/questions/12609008/…
猜你喜欢
  • 1970-01-01
  • 2015-03-24
  • 2012-06-21
  • 2014-04-04
  • 1970-01-01
  • 2016-03-22
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多