集合上的幻影DSL问题包含和排序

时间:2016-03-06 18:37:39

标签: scala cassandra phantom-dsl

我使用Phantom DSL编写此scala代码来查询cassandra

  def getByGenreAndYear(genre: List[String], year: Int) : Future[Seq[Movie]] = {
    var criteria = select.where(_.genre contains genre.head)
    criteria = genre.tail.foldLeft(criteria){(accum, i) => accum.and(_.genre contains i)}
    criteria.and(_.year eqs year)
    criteria.allowFiltering().fetch()
  }

它有效,但我有几个问题

  • 设置包含

查询集合是否包含值时。是否像我一样构建查询条件是正确的?基本上我对我们要检查的每个值都有一个AND子句。这可以像

一样完成
select.where(_.genre contains genreList)
  • 排序

我无法生成排序查询。当我尝试做的时候

  def getByGenreAndYear(genre: List[String], year: Int) : Future[Seq[Movie]] = {
    var criteria = select.where(_.genre contains genre.head)
    criteria = genre.tail.foldLeft(criteria){(accum, i) => accum.and(_.genre contains i)}
    criteria.and(_.year eqs year)
    criteria.orderBy(_.year desc)
    criteria.allowFiltering().fetch()
  }

代码甚至不编译

1 个答案:

答案 0 :(得分:1)

包含查询

您无法同时对多个值进行public static ArrayList<Byte> hammingNeighbours(byte input, int maxDistance){ ArrayList<Byte> neighbours = new ArrayList<>(); neighbours.add(input); byte value;; byte mask = 1; for (int i = 0; i < 8; i++) { value = (byte) (input ^mask); neighbours.add(value); mask = (byte) (mask << 1); } return neighbours; } 次查询。您有几种方法可以实现上述目标。第一种是使用过滤并构建查询。

contains

除了幻像查询构建器不可变之外,您正在此处执行此操作,您执行的每个操作都将创建一个新的def getByGenreAndYear(genre: List[String], year: Int): Future[Seq[Movie]] = { val rootQuery = select.where(_.genre contains genre.head) genre.tail.foldLeft(rootQuery){ (accum, i) => accum.and(_.genre contains i)} .and(_.year eqs year) .orderBy(_.year desc) .allowFiltering().fetch() } 实例。这是有充分理由的。

另一种方法是对期货进行排序而不是在Cassandra中进行过滤,这并不总是非常明智。

Query

此时,对单个查询中的多个值进行def getByGenreAndYear(genre: List[String], year: Int): Future[Seq[Movie]] = { // This will create a future to query for a single value. val futures = genre.map(item => select.where(_.year eqs year).and(_.genre contains item).fetch()) // This will sequence the entire set, produce a list of lists, flatten it and create an union, and deduplicate by set conversion granted you define the right `hashCode` method on the `Movie` class. Future.sequence(futures) map { // You could also probably get away with lists.flatten lists => lists.foldRight(Nil)((item, acc) => item ::: acc)).toSet } } 查询是不可能的。你收到一个错误:

CONTAINS

然而这有效:

cql select * from marvis.expenses where tags contains ('food', 'office-food'); InvalidRequest: code=2200 [Invalid query] message="Invalid tuple type literal for value(tags) of type text"

<强>分拣

要实现排序,您需要复合复合键,您只能按列的 select * from marvis.expenses where tags contains 'food' and tags contains 'office-food' ALLOW FILTERING; 部分排序,而不是分区键部分。如果需要,请查看this tutorial以获取有关Cassandra索引的更多详细信息。