2016-05-06 30 views
0

我正在構建一個簡單的Scala Play應用程序,該應用程序使用Scala的Phantom DSL驅動程序將數據存儲在Cassandra DB中。 Cassandra的一個很好的功能是可以進行部分更新,即只要您提供了關鍵列,您就不必爲表中的所有其他列提供值。 Cassandra會根據密鑰將數據合併到您現有的記錄中。Cassandra和Phantom DSL部分插入

不幸的是,這似乎不適用於Phantom DSL。我有一個包含多列的表,我希望能夠進行更新,只爲鍵和其中一個數據列指定值,然後讓Cassandra像往常一樣將它合併到記錄中,同時將所有其他數據列該記錄保持不變。

但是,如果您沒有在插入/更新語句中指定值,Phantom DSL將用空覆蓋現有的列。

有沒有人知道這方面的解決方法?我不想每次都讀/寫所有的數據列,因爲最終數據列會很大。

僅供參考我使用同樣的方法我的幻影編碼在這些例子中:

https://github.com/thiagoandrade6/cassandra-phantom/blob/master/src/main/scala/com/cassandra/phantom/modeling/model/GenericSongsModel.scala

回答

2

這將是非常高興看到一些代碼,但部分更新是可能的幻象。幻影是一個不可改變的構建器,默認情況下它不會覆蓋任何空值。如果你沒有指定一個值,它將不會做任何事情。

database.table.update.where(_.id eqs id).update(_.bla setTo "newValue") 

將產生一個查詢,其中只有您明確設置爲something的值將被設置爲null。請提供一些代碼示例,您的問題看起來很奇怪,因爲查詢不跟蹤表列以自動添加缺少的內容。

更新

如果你想刪除列的值,例如,將其設置爲null裏面卡桑德拉基本上,幻影提供了不同的語法,做同樣的事情:

database.table.delete(_.col1, _.col2).where(_.id eqs id)` 

此外,還甚至可以用同樣的方式刪除地圖條目:

database.table.delete(_.props("test"), _.props("test2").where(_.id eqs id) 

這個假設propsMapColumn[Table, Record, String, _],因爲props.apply(key: T)是類型安全的,因此它將遵循您爲map列定義的鍵類型。

+0

謝謝,弗拉維安。我的代碼現在處於流動狀態,並且比上面鏈接的示例應用程序稍微複雜一點,所以我不能輕易將其放入此文章中。但是,我現在想知道是否可以通過在我的Scala/Phantom代碼中將列聲明爲選項來解決問題,因爲可能我的Scala數據類是問題。如果這不起作用,我會嘗試更新方法。謝謝你的幫助。 –

+0

杜。我認爲問題在於我正在使用插入來執行更新。在Cassandra中,這很好,因爲Cassandra無論如何都將它視爲一個upsert,對於我不需要關心記錄是否已經存在或不需要關注的用例,這是很好的,因爲我只寫了關鍵字和一個或兩個特定字段:默認的Cassandra行爲就是我想要的。但它看起來像Phantom希望你明確地進行更新或插入,取決於密鑰是否已經存在。我會嘗試使用更新,就像Flavian建議的那樣,看看會發生什麼。 –

+0

更新(_。bla setTo「newvalue」)不再適用於幻像1.27.0。它看起來只有修改(_。bla setTo「newvalue」)可用。但是,它不會更新具有空值的列,這是此處的問題。 – yang