tl; dr
はい、null
一意の「実際の」値を適用しながら、フィールドが設定されているか定義されていない複数のドキュメントを持つことが可能です。
要件:
- MongoDB v3.2以降。
- 事前に具体的な値のタイプを知っている(たとえば、常にa
string
かそうでないobject
場合null
)。
詳細に興味がない場合は、このimplementation
セクションに進んでください。
より長いバージョン
@Nolanの回答を補足するために、MongoDB v3.2以降、フィルター式で部分一意インデックスを使用できます。
部分フィルター式には制限があります。以下のみを含めることができます。
- 等式(フィールド:値または
$eq
演算子の使用)、
$exists: true
式、
$gt
、$gte
、$lt
、$lte
表情、
$type
式、
$and
トップレベルの演算子のみ
つまり、自明な表現{"yourField"{$ne: null}}
は使用できません。
ただし、フィールドで常に同じタイプを使用すると仮定すると、$type
式を使用できます。
{ field: { $type: <BSON type number> | <String alias> } }
MongoDB v3.6は、配列として渡すことができる複数の可能なタイプを指定するためのサポートを追加しました。
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
つまり、そうでない場合、値は複数の複数のタイプのいずれかになることができますnull
。
したがって、email
以下の例のフィールドに値string
またはbinary data
値のいずれかを許可する場合、適切な$type
式は次のようになります。
{email: {$type: ["string", "binData"]}}
実装
マングース
あなたはマングーススキーマでそれを指定することができます:
const UsersSchema = new Schema({
name: {type: String, trim: true, index: true, required: true},
email: {
type: String, trim: true, index: {
unique: true,
partialFilterExpression: {email: {$type: "string"}}
}
}
});
または直接コレクションに追加します(ネイティブのnode.jsドライバーを使用します):
User.collection.createIndex("email", {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
});
ネイティブのmongodbドライバー
を使用して collection.createIndex
db.collection('users').createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
},
function (err, results) {
// ...
}
);
mongodbシェル
を使用してdb.collection.createIndex
:
db.users.createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {$type: "string"}
}
})
これにより、null
電子メールを使用して、または電子メールフィールドをまったく使用せずに、同じ電子メール文字列を使用せずに複数のレコードを挿入できます。