如何使用phantom-dsl实现Cassandra计数器列?

时间:2016-05-16 00:12:32

标签: scala cassandra-2.0 phantom-dsl

这是这个问题的扩展:

How to increment Cassandra Counter Column with phantom-dsl?

此问题也被提出here

Thiagos example两个表中; '歌' &安培; ' songs_by_artist'两者具有相同的行但具有不同的分区(主键/群集列)

CREATE TABLE test.songs (
    song_id timeuuid PRIMARY KEY,
    album text,
    artist text,
    title text
);

CREATE TABLE test.songs_by_artist (
    artist text,
    song_id timeuuid,
    album text,
    title text,
    PRIMARY KEY (artist, song_id)
) WITH CLUSTERING ORDER BY (song_id ASC);

这意味着在SongsService内的两个表中插入,更新和删除相同的基本数据/行。

例如,您如何拥有一个表格,例如' artist_songs_counts',以及列' song_id' (K)和' num_songs' (++)并确保' SongsService'为每个表添加相应的行; '歌' &安培; ' songs_by_artist' &安培; ' artist_songs_counts' (其中有不同数量的行,但应链接信息,例如艺术家信息)。

CREATE TABLE test.artist_songs_counts (
    artist text PRIMARY KEY,
    num_songs counter);

1 个答案:

答案 0 :(得分:2)

SongsService扩展ProductionDatabaseProvider,它为您提供了一个名为database的对象,您可以访问某个数据库下的表:

/**
    * Find songs by Id
    * @param id
    * @return
    */
  def getSongById(id: UUID): Future[Option[Song]] = {
    database.songsModel.getBySongId(id)
  }

甚至更好,同时处理两个表:

  /**
   * Save a song in both tables
   *
   * @param songs
   * @return
   */
  def saveOrUpdate(songs: Song): Future[ResultSet] = {
    for {
      byId <- database.songsModel.store(songs)
      byArtist <- database.songsByArtistsModel.store(songs)
    } yield byArtist
  }

由于通过database对象可以访问属于特定数据库的所有表,我将通过以下方式为艺术家实现一个计数器:

def increment(artist: String): Future[ResultSet] = {
  update
    .where(_.artist eqs artist)
    .modify(_.numSongs += 1)
    .future()
}

然后saveOrUpdate方法可以写成如下:

def saveOrUpdate(song: Song): Future[ResultSet] = {
    for {
      byId <- database.songsModel.store(songs)
      byArtist <- database.songsByArtistsModel.store(songs)
      counter <- database.artistSongsCounter.increment(song.artist)
    } yield byArtist
  }