Eu queria saber se existe uma maneira de forçar uma entrada de coleção exclusiva, mas apenas se a entrada não for nula . e Esquema de amostra:
var UsersSchema = new Schema({
name : {type: String, trim: true, index: true, required: true},
email : {type: String, trim: true, index: true, unique: true}
});
'e-mail', neste caso, não é necessário, mas se 'e-mail' for salvo, quero ter certeza de que esta entrada é exclusiva (em um nível de banco de dados).
As entradas vazias parecem obter o valor 'null', portanto, todas as entradas sem e-mail travam com a opção 'exclusivo' (se houver um usuário diferente sem e-mail).
No momento, estou resolvendo no nível do aplicativo, mas adoraria salvar a consulta do banco de dados.
THX
email
campo, não onde ele realmente tem o valornull
. Veja a resposta atualizada.tl; dr
Sim, é possível ter vários documentos com um campo definido como
null
ou não definido, enquanto impõe valores "reais" exclusivos.requisitos :
string
ouobject
quando nãonull
).Se você não estiver interessado nos detalhes, sinta-se à vontade para pular para a
implementation
seção.versão mais longa
Para complementar a resposta de @Nolan, começando com MongoDB v3.2, você pode usar um índice exclusivo parcial com uma expressão de filtro.
A expressão de filtro parcial tem limitações. Só pode incluir o seguinte:
Isso significa que a expressão trivial
{"yourField"{$ne: null}}
não pode ser usada.No entanto, supondo que seu campo sempre use o mesmo tipo , você pode usar uma
$type
expressão .MongoDB v3.6 adicionou suporte para especificar vários tipos possíveis, que podem ser passados como uma matriz:
o que significa que permite que o valor seja de vários tipos, quando não
null
.Portanto, se quisermos permitir que o
email
campo no exemplo abaixo aceite umstring
ou, digamos,binary data
valores, uma$type
expressão apropriada seria:implementação
mangusto
Você pode especificá-lo em um esquema mongoose:
ou adicione-o diretamente à coleção (que usa o driver node.js nativo):
driver mongodb nativo
usando
collection.createIndex
concha mongodb
usando
db.collection.createIndex
:Isso permitirá inserir vários registros com um
null
e - mail ou sem nenhum campo de e-mail, mas não com a mesma sequência de e-mail.fonte
unique
esparse
). Atualizei meu esquema com esta resposta, eliminei meu índice existente e funcionou perfeitamente.Apenas uma atualização rápida para aqueles que estão pesquisando este tópico.
A resposta selecionada funcionará, mas você pode considerar o uso de índices parciais.
Mais documentação sobre índices parciais: https://docs.mongodb.com/manual/core/index-partial/
fonte
Na verdade, apenas o primeiro documento onde o campo "email" como não existe será salvo com sucesso. Os salvamentos subsequentes onde "e-mail" não estiver presente falharão ao fornecer o erro (consulte o trecho de código abaixo). Para saber o motivo, consulte a documentação oficial do MongoDB com relação a índices exclusivos e chaves ausentes aqui em http://www.mongodb.org/display/DOCS/Indexes#Indexes-UniqueIndexes .
Por definição, o índice exclusivo só pode permitir que um valor seja armazenado apenas uma vez. Se você considerar nulo como um desses valores, ele só pode ser inserido uma vez! Você está correto em sua abordagem, garantindo e validando-a no nível do aplicativo. É assim que pode ser feito.
Você também pode gostar de ler este http://www.mongodb.org/display/DOCS/Querying+and+nulls
fonte