2013-02-12 17 views
2

在RavenDB中使用URL作爲鍵的最佳方式是什麼?在RavenDB中作爲鍵的URL

不幸的是,更新一個項目的語義在文檔中並不清楚:如果密鑰以反斜槓結尾,它總是一個插入,否則它可能是一個更新,如果該鍵已經存在。

URLs can end up in slash,而RavenDB uses terminating slashes for key generation

RavenDB還支持身份的概念,例如,如果你需要 的ID是連續的。通過在 實體創建一個字符串ID屬性,並將其設置爲以斜槓(/)結尾的值,可以 告訴RavenDB使用,作爲對你的實體的一個關鍵前綴。在調用SaveChanges()後,前綴 後跟下一個可用的整數ID將爲您實體的ID爲 的ID。 ,並且正斜槓不能重新配置。所以它並不真正「支持」它,而是強制執行它。

編輯:同樣的RavenDB文檔頁面的狀態下面,這不符合所觀察到的行爲:

您可以分配到一個文檔,你可以想像的任何ID。 一切都會正常工作,但是你必須要知道 是某種標識,否則會導致性能問題時,與自定義生成的ID 文件數量非常高(百萬 文件)。

的選項有: 1.修改你的URL刪除結束斜槓 2. URL編碼的URL(由RavenDB維護者的建議) 3.修改架構和使用數據庫生成的ID

選項1在大多數情況下應該是安全的。選項2會使密鑰不可讀,另外我還沒有設法使它工作(可能是RavenDB或我的代碼中的錯誤)。選項3似乎不必要地使模式複雜化。

什麼是最好的行動過程中,有什麼看法?

回答

3

它是偏愛我想的問題 - 但我不認爲網址取得很好的鑰匙。其他人不同意。請參閱支持論壇上的this discussion

我會好好想想爲什麼你需要它作爲一個重點,如果你能索引網址來代替。例如:

public class Site 
{ 
    public string Id { get; set; } // such as "sites/1" 
    public string Name { get; set; } 
    public string Url { get; set; } 
} 

var q = session.Query<Site>().Where(x=> x.Url == "http://foo/bar"); 

使用它的關鍵是一個URL應該是唯一代表資源的說法,但是這並非總是如此,當你考慮的http和https,可選查詢字符串參數,

此外,RavenDB文檔鍵不區分大小寫,而URL(一般情況下)敏感。許多Web服務器將忽略基本URL的大小寫,但是仍然由Web應用程序決定如何區分大小寫或不敏感查詢字符串參數。因此,http://foo/bar?q=abchttp://foo/bar?q=ABC完全有可能引用兩個單獨的資源,但它們在Raven中將被視爲相同的文檔密鑰。

如果你覺得你必須使用網址作爲文件的密鑰,然後根據Ayende說,你應該以某種方式逃避他們,大概是這個樣子:

// to escape 
var key = Uri.EscapeDataString(url); 


// to unescape 
var url = Uri.UnescapeDataString(key); 

我敢肯定有其他逃避或編碼格式會工作也是如此,這似乎是最簡單的一個。

1

你需要躲避URL,如果你想使用它作爲一個文件密鑰。

1

讓我從練習者的角度在這裏侃侃而談。我必須將OpenIds作爲文檔密鑰存儲在RavenDb中,所以很自然地出現了這個問題。儘管最近的版本已經修復了與作爲文檔密鑰的esaped URL相關的問題,但它仍然不是我可以推薦的,因爲我已經用它來解決各種錯誤。我報告了他們中的一些,他們得到了解決,但我最終放棄了。

我第一次開始使用URL上的base64編碼,但很快發現這可能會導致超過RavenDb限制的長文檔密鑰,您將看到服務器端Esent ColumnTooBig異常。

由於這些ID太長(且合法的URL可能是up to 2000 characters),我已經開始使用它們的base64編碼SHA-Hashes。不能說它是優雅的,但它工作得很好。