如何使用 phantom-dsl 实现 Cassandra 计数器列?
How to Implement Cassandra Counter Columns with phantom-dsl?
这是对这个问题的扩展:
这个问题也有人问过 here。
在Thiagos example两个table; 'songs' & '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 中的两个 table 之间插入、更新和删除使用相同的基础数据/行。
例如,您将如何得到一个 table,例如 'artist_songs_counts',其中包含列 'song_id' (K) 和 'num_songs' (++),并确保 'SongsService' 向每个 table 添加相应的行; 'songs' & 'songs_by_artist' & 'artist_songs_counts'(行数不同但应该链接信息,例如艺术家信息)。
CREATE TABLE test.artist_songs_counts (
artist text PRIMARY KEY,
num_songs counter);
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
}
这是对这个问题的扩展:
这个问题也有人问过 here。
在Thiagos example两个table; 'songs' & '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 中的两个 table 之间插入、更新和删除使用相同的基础数据/行。
例如,您将如何得到一个 table,例如 'artist_songs_counts',其中包含列 'song_id' (K) 和 'num_songs' (++),并确保 'SongsService' 向每个 table 添加相应的行; 'songs' & 'songs_by_artist' & 'artist_songs_counts'(行数不同但应该链接信息,例如艺术家信息)。
CREATE TABLE test.artist_songs_counts (
artist text PRIMARY KEY,
num_songs counter);
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
}