tl; dr
Да, возможно иметь несколько документов с полем, установленным null
или не определенным, с применением уникальных «фактических» значений.
требования :
- MongoDB v3.2 +.
- Зная заранее свой конкретный тип (типы) значений (например, всегда а
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
электронной почтой или вообще без поля электронной почты, но не с той же строкой электронной почты.