Мне было интересно, есть ли способ принудительно создать уникальную запись коллекции, но только если запись не равна нулю . e Пример схемы:
var UsersSchema = new Schema({
name : {type: String, trim: true, index: true, required: true},
email : {type: String, trim: true, index: true, unique: true}
});
«электронная почта» в этом случае не требуется, но если «электронная почта» сохранена, я хочу убедиться, что эта запись уникальна (на уровне базы данных).
Кажется, что пустые записи получают значение «null», поэтому каждая запись без электронной почты вылетает с опцией «уникальный» (если есть другой пользователь без электронной почты).
Прямо сейчас я решаю это на уровне приложения, но хотел бы сохранить этот запрос к базе данных.
Спасибо
email
поля, а не там, где оно на самом деле имеет значениеnull
. См. Обновленный ответ.tl; dr
Да, возможно иметь несколько документов с полем, установленным
null
или не определенным, с применением уникальных «фактических» значений.требования :
string
илиobject
когда нетnull
).Если вас не интересуют подробности, не стесняйтесь переходить к
implementation
разделу.более длинная версия
Чтобы дополнить ответ @Nolan, начиная с MongoDB v3.2, вы можете использовать частичный уникальный индекс с выражением фильтра.
У выражения частичного фильтра есть ограничения. Он может включать только следующее:
Это означает, что использовать банальное выражение
{"yourField"{$ne: null}}
нельзя.Однако, предполагая, что ваше поле всегда использует один и тот же тип , вы можете использовать
$type
выражение .В MongoDB v3.6 добавлена поддержка для указания нескольких возможных типов, которые могут быть переданы в виде массива:
что означает, что он позволяет значению быть любого из множества нескольких типов, когда это не так
null
.Следовательно, если мы хотим, чтобы
email
поле в приведенном ниже примере могло принимать либо,string
либо, скажем,binary data
значения, подходящим$type
выражением было бы:реализация
мангуста
Вы можете указать это в схеме мангуста:
или напрямую добавить его в коллекцию (которая использует собственный драйвер node.js):
родной драйвер mongodb
с помощью
collection.createIndex
оболочка mongodb
используя
db.collection.createIndex
:Это позволит вставить несколько записей с
null
электронной почтой или вообще без поля электронной почты, но не с той же строкой электронной почты.источник
unique
иsparse
). Я обновил свою схему этим ответом, отказался от существующего индекса, и он работал как шарм.Просто быстрое обновление для тех, кто исследует эту тему.
Выбранный ответ будет работать, но вы можете рассмотреть возможность использования вместо него частичных индексов.
Дополнительная документация по частичным индексам: https://docs.mongodb.com/manual/core/index-partial/
источник
Фактически, только первый документ, в котором отсутствует поле «email», будет успешно сохранен. Последующие сохранения без «электронной почты» будут завершаться ошибкой (см. Фрагмент кода ниже). По этой причине посмотрите официальную документацию MongoDB относительно уникальных индексов и отсутствующих ключей здесь, на http://www.mongodb.org/display/DOCS/Indexes#Indexes-UniqueIndexes .
По определению уникальный индекс может допускать сохранение только одного значения только один раз. Если вы рассматриваете null как одно из таких значений, его можно вставить только один раз! Вы правы в своем подходе, гарантируя и проверяя его на уровне приложения. Вот как это можно сделать.
Вы также можете прочитать это http://www.mongodb.org/display/DOCS/Querying+and+nulls
источник