2016-03-06 42 views
1

我一直在使用幻象DSL查詢卡桑德拉幻象DSL問題包含和排序

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() 
    } 

它可以這樣寫Scala代碼,但我有幾個問題

  • 集包含

查詢某個集合是否包含值時。像我所做的那樣構建查詢條件是否正確?基本上我對每個我們想要檢查的值都有一個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() 
    } 

代碼desn't甚至編譯

+0

你能指定確切的編譯錯誤嗎?表格模式也不在這裏,我星期一早上只能運用這麼多的洞察力。 – flavian

回答

1

包含查詢

你不能在同一時間做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() 
    } 

這是你在這裏做除了幻影查詢生成器是什麼不變,你將創建一個新Query實例的每一個操作。這有一個很好的理由。

另一種方法是在Cassandra中對期貨進行排序而不進行篩選,這並不總是非常明智的。

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;

排序

要實現排序,你需要一個複合複合關鍵,您只能按排序列的10部分,而不是分區鍵部分。如果需要,請查看this tutorial瞭解有關Cassandra索引的更多詳細信息。