2015-11-06 32 views
2

是否可以製作複合索引,其中一個字段具有固定值?固定值字段的貓鼬複合指數

比方說,我想避免用戶使用同一個電子郵件爲不同的帳戶,但只是爲了普通的用戶帳戶,我想讓管理員在任意位置使用郵件,甚至有一個普通用戶帳戶和使用相同電子郵件的管理帳戶

User.index({ username: 1, email: 1 }, { unique: true }) 

沒用,因爲它不允許管理員重複使用電子郵件。是否有可能做類似的事情?

User.index({ role: "regular_user", username 1, email: 1}, { unique: true }); 
+0

我發佈了一個關於索引的答案,這可以幫助你決定它是否適合你創建一個複合索引,其中一個字段具有固定值。 http://stackoverflow.com/questions/33545339/how-does-the-order-of-compound-indexes-matter-in-mongodb-performance-wise/33546159#answer-33546159 – inspired

+0

很好的答案。實際上,就我而言,我正在改進用於mongoose的模式繼承包裝器(https://github.com/briankircho/mongoose-schema-extend),並且必須將所有唯一密鑰更改爲鑑別器/密鑰唯一索引,但只適用於將這些字段定義爲唯一的鑑別器值。上面的例子是我能找到的最簡單的解釋。 –

+0

事情是怎麼發生的? – inspired

回答

2

路易斯,

在問候你給的例子。如果創建唯一的複合索引,則各個鍵可以具有相同的值,但索引條目中存在的鍵的值組合只能出現一次。所以如果我們有一個獨特的索引{"username" : 1, "role" : 1}。下面的刀片是合法的:

> db.users.insert({"username" : "Luis Sieira"}) 
> db.users.insert({"username" : "Luis Sieira", "role" : "regular"}) 
> db.users.insert({"username" : "Luis Sieira", "role" : "admin"}) 

如果你試圖插入的任何上述文件的第二份副本,您會導致重複鍵異常。

你的方案

我認爲,如果你增加了一個allowance領域的架構。當你插入新帳戶的管理員。您可以爲其管理員津貼添加不同的值。如果添加唯一索引{"username":1,"email":1, "allowance" : 1}

你可以做以下的插入,合法:

>db.users.insert({"username" : "inspired","email": "[email protected]", "allowance": 0}) 
>db.users.insert({"username" : "inspired","email": "[email protected]", "allowance": 1}) 
>db.users.insert({"username" : "inspired","email": "[email protected]", "allowance": 2}) 
>db.users.insert({"username" : "inspired","email": "[email protected]", "allowance": 3}) 

當然,你必須從客戶端處理某些邏輯,但是這將允許您使用0的配額代碼爲regular帳戶,然後允許您每次在admin創建另一個帳戶時保存更高的配額代碼(增加或增加自定義值)。

我希望這提供了一些方向,使用獨特的複合索引。

1

您正處在正確的軌道上。首先最重要的,如果你定義與role索引這樣

User.index({role: 1, username: 1, email: 1}, { unique: true }); 

蒙戈將使用null對於不指定role領域的文件。如果插入的用戶未指定role並嘗試再次添加,則會出現錯誤,因爲數據庫中已存在三個字段。所以你可以通過不包括角色來使用它(或者你可以使用預定義的值來獲得更好的閱讀效果,比如你建議的regular_user)。

現在,棘手的部分是迫使索引允許管理員的唯一性約束。最好的解決方案是生成一些散列並將其添加到角色中。所以,如果你只是添加角色像admin_user管理員,你不會繞過約束。同時,使用像admin_user_635646這樣的角色(始終以不同的後綴)將允許您多次插入相同的管理員。