1

我希望有一个如下表:

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 谓词。这仍然是真的吗?如果是这样,我将不得不使列 < Data 成为 PK 的一部分。
  2. 是否仍然必须从左到右包含所有列并且不能跳过任何列?
  3. 我的设计中是否有任何非最佳点?
  4. 我想添加一列“材料”,它是产品系列中可能的材料数组。想想披萨配料,并查询“WHERE Materials IN ('Pineapple')”。在不创建单独的材料倒排索引然后对上述查询执行手动交集的情况下,在 Cassandra 中是否还有其他 [更优雅] 的处理方式?
4

2 回答 2

3

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

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

于 2012-09-06T14:10:25.233 回答
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 <= 40 将返回一个连续切片,但使用 masslow 和其他列过滤结果集将无法正常工作不会导致连续切片。顺便说一句,pricelow = 10 和 masslow <= 20 和 masslow >=10 应该可以工作[用 phpcassa 测试],因为它会再次产生一个连续的切片。

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

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

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

于 2012-09-06T14:42:51.260 回答