我使用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()
}
代码甚至不编译
答案 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索引的更多详细信息。