1

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

コードはコンパイルさえしません

4

1 に答える 1

1

クエリを含む

contains複数の値に対して同時にクエリを実行することはできません。上記を実現するには、いくつかの方法があります。1 つ目は、フィルタリングを使用してクエリを作成することです。

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

これは、ファントム クエリ ビルダーがimmutableであることを除いて、ここで行っていることです。実行するすべての操作で新しいQueryインスタンスが作成されます。それには非常に正当な理由があります。

もう 1 つの方法は、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では、1 つのクエリで複数の値に対してクエリを実行することはできません。次のエラーが表示されます。

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;

並べ替え

並べ替えを行うには、複合キーまたは複合キーが必要です。パーティション キーclustering keyの部分ではなく、列の部分でのみ並べ替えることができます。必要に応じて、Cassandra インデックス作成の詳細については、このチュートリアルをご覧ください。

于 2016-03-07T10:17:12.863 に答える