2012-06-18 73 views
7

我正在使用java/morphia來處理mongodb。從Java層使用默認的ObjectId不是很方便。我想使它成爲String類型,同時使用ObjectId保留密鑰生成過程,例如_id = new ObjectId.toString()我可以使用String作爲mongodb文檔的ID類型嗎?

我想知道是否有這樣的副作用?例如,它會以任何方式影響數據庫性能或導致關鍵衝突嗎?它會影響分片環境...

+0

你能解釋一下爲什麼ObjectId不方便嗎?你可以很容易地從'id = new ObjectId(str)'這樣的字符串中重新創建一個字符串。 –

+0

String是每個Java程序中使用的類型,而ObjectId不是。我不想爲其他使用我的庫的組件引入新的類型。也許這將需要嗎啡,MongoDB的和BSON庫導入,它仍然是更好的,如果用我的圖書館的人是透明的MongoDB的類型,包括的ObjectId –

+0

嗯......但如果你的庫存儲在蒙戈數據,也會不mongo.jar無論如何都需要在classpath中?此外,還有一個開銷創建和垃圾收集大量的字符串。 –

回答

18

您可以對_id字段使用任何類型的值(數組除外)。如果您選擇不使用ObjectId,則必須以某種方式保證值的唯一性(將ObjectId轉換爲字符串將執行)。如果您嘗試插入重複密鑰,則會發生錯誤,您必須對其進行處理。

我不確定當你試圖將兩個具有相同_id的文檔插入不同的分片時它對分片羣集會有什麼影響。我懷疑它會讓你插入,但這會稍後咬你。 (我將不得不測試這個)。

這就是說,你應該沒有問題_id = (new ObjectId).toString()

+0

這很好。謝謝! –

+0

你的第二句和第三句是互相反對的。第三個是正確的。不要懷疑答案。另外,'_id's可以保存'array'類型的值。 – Dyin

+0

他們究竟相互矛盾呢? –

4

我實際上做了同樣的事情,因爲我有一些問題將ObjectId轉換爲JSON。

然後我不喜歡的東西

@Id 
private String id; 
public String getId() { 
    return id(); 
} 
public void setId(String id) { 
    this.id = id; 
} 

而且一切正常,直到我決定更新先前插入的文件,當我憑身份證拿到了對象通過JSON發送到頁面,並收到相同的更新對象也通過JSON發佈,然後使用數據存儲的保存功能,而不是更新之前的數據,而是插入新的文檔而不是更新已有的數據。

即使最糟糕的是,新文檔的ID也比先前插入的文檔的ID相同,但我認爲這是不可能的。

無論如何,我將私人對象設置爲一個ObjectID,並將get set設置爲字符串,然後按預期方式工作,不確定這有助於您的案例。

@Id 
private ObjectId id; 
public String getId() { 
    return id.toString(); 
} 
public void setId(String id) { 
    this.id = new ObjectId(id); 
} 
1

是的,你可以使用一個字符串作爲你的_id。

我推薦它只有當你有一些價值(在文檔中),自然是一個很好的獨特的關鍵。我在一個集合中使用了這種設計,其中有一個字符串地理標籤,形式爲「xxxxyyyy」;這個獨特的每文檔領域將會在文件我不得不建立一個索引...所以爲什麼不把它用作關鍵? (這避免了一個額外的鍵值對,並且避免了集合上的第二個索引,因爲MondoDB自然會在「_id」上建立一個索引。給定集合的大小,這些都會大大節省空間。)

但是,從你的問題的口氣(「ObjectIDs不是很方便」),如果你想使用一個字符串的唯一原因是你不想被搞糊塗搞清楚如何整潔地管理ObjectIDs .. 。我建議你值得你的時間來圍繞他們。我相信他們沒有麻煩......一旦你找到了麻煩與他們。

否則:你有什麼選擇?你會在每次使用MongoDB的時候編寫字符串ID嗎?

+1

嘿謝謝回到我近四年前問的問題。從那以後,我認爲我對MongoDB有了更多的瞭解。現在我認爲將ObjectId存儲爲字符串實在是個不錯的主意,因爲ObjectId實際上是三個整數,而String的表示形式是24個字符,這在空間和時間上都是無效的。 –

1

我想補充一點,它並不總是使用自動生成的BSON對象ID作爲唯一標識符是一個好主意,如果它被傳遞到應用程序:它可能由用戶進行操作。 ObjectID似乎是按順序生成的,因此如果您未能實施必要的授權機制,惡意用戶可能會簡單地增加他擁有的價值,以訪問他不應訪問的資源。

因此使用UUID類型標識符將提供安全貫通朦朧的層。當然,授權(允許該用戶訪問所請求的資源)是必須的,但您應該瞭解前面提到的ObjectID功能。

要獲得兩全其美的,產生它的對象ID的長度(12個或24個字符)匹配UUID並用它來創建自己的ObjectID類型的_id。

+2

「如果你未能實施必要的授權」你就註定了。模糊不安全。它只是在愚弄自己「我們很安全」。 – Piohen

+0

@Piohen人們如何閱讀第二段的內容超出了我的想象...... –

相關問題