consulta MongoDB com uma condição 'ou'
-
18-09-2019 - |
Pergunta
Então, eu tenho um documento incorporado que os membros do grupo faixas. Cada documento incorporado tem um ID apontando para o grupo em outra coleção, uma data de início, e um opcional data expirar.
Eu quero consulta para os atuais membros de um grupo. "Current" significa a hora de início é inferior ao tempo atual, ea expirar o tempo é maior do que o tempo ou nulo atual.
Esta consulta condicional é totalmente bloqueando-me. Eu poderia fazê-lo, executando duas consultas e fundindo os resultados, mas que parece feio e requer o carregamento de todos os resultados de uma só vez. Ou eu poderia usar como padrão o tempo expirar para uma data arbitrária no futuro distante, mas que parece ainda mais feio e potencialmente frágil. Em SQL Eu tinha acabado de expressá-lo com "(expira> = Now ()) OU (expira IS NULL)" - mas eu não sei como fazer isso em Mongo
.Todas as idéias? Muito obrigado de antecedência.
Solução
Apenas pensei em atualizar em caso alguém se depara com esta página no futuro. A partir de 1.5.3, mongo agora suporta uma verdadeira $ ou operador: http : //www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
A sua consulta de "(expira> = Now ()) OU (expira IS NULL)" podem agora ser processado como:
{$or: [{expires: {$gte: new Date()}}, {expires: null}]}
Outras dicas
No alguém encontrar casos útil, www.querymongo.com faz a tradução entre o SQL e MongoDB, incluindo cláusulas OR . Pode ser realmente útil para descobrir a sintaxe quando você sabe o equivalente SQL.
No caso de OR, parece que este
SQL:
SELECT * FROM collection WHERE columnA = 3 OR columnB = 'string';
MongoDB:
db.collection.find({
"$or": [{
"columnA": 3
}, {
"columnB": "string"
}]
});
Use "dentro" ou "onde".
Isso vai ser algo como isto:
db.mycollection.find( { $where : function() {
return ( this.startTime < Now() && this.expireTime > Now() || this.expireTime == null ); } } );
db.Lead.find (
{"name": {'$regex' : '.*' + "Ravi" + '.*'}},
{
"$or": [{
'added_by':"arunkrishna@aarux.com"
}, {
'added_by':"aruna@aarux.com"
}]
}
);
Usando uma consulta $where
será lenta, em parte porque ele não pode usar índices. Para este tipo de problema, eu acho que seria melhor para armazenar um alto valor para o campo "expira", que naturalmente será sempre maior do que agora (). Você pode armazenar uma muito elevados milhões data de anos no futuro, ou usar um tipo separado para indicar nunca mais. A ordem de classificação de tipo cruzado é definida em aqui .
Um esvaziar Regex ou MaxKey (se você linguagem suporta) são boas escolhas.