Запрос MongoDB с условием "или"
Итак, у меня есть встроенный документ, который отслеживает членство в группах. Каждый внедренный документ имеет идентификатор, указывающий на группу в другой коллекции, дату начала и дополнительную дату истечения срока действия.
Я хочу запросить для текущих членов группы. "Ток" означает, что время начала меньше текущего времени, а время истечения превышает текущее время ИЛИ null.
Этот условный запрос полностью блокирует меня. Я мог бы сделать это, выполнив два запроса и объединив результаты, но это кажется уродливым и требует загрузки во все результаты сразу. Или я мог бы по умолчанию истекать время до какой-то произвольной даты в далеком будущем, но это кажется еще более уродливым и потенциально хрупким. В SQL я бы просто выразил это с помощью "(expires >= Now()) ИЛИ (истекает IS NULL)" - но я не знаю, как это сделать в Mongo.
Любые идеи? Большое спасибо заранее.
Ответы
Ответ 1
Просто подумал, что я обновляю в случае, если кто-нибудь наткнется на эту страницу в будущем. Начиная с 1.5.3, mongo теперь поддерживает реальный $или оператор: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
Ваш запрос "(expires >= Now()) ИЛИ (истекает IS NULL)" теперь можно отобразить как:
{$or: [{expires: {$gte: new Date()}}, {expires: null}]}
Ответ 2
В случае, если кто-либо найдет это полезным, www.querymongo.com делает перевод между SQL и MongoDB, включая предложения OR. Это может быть очень полезно для определения синтаксиса, когда вы знаете эквивалент SQL.
В случае операторов OR это выглядит как
SQL:
SELECT * FROM collection WHERE columnA = 3 OR columnB = 'string';
MongoDB:
db.collection.find({
"$or": [{
"columnA": 3
}, {
"columnB": "string"
}]
});
Ответ 3
Объекты запроса в Mongo по умолчанию и выражения вместе. В настоящее время Mongo не включает оператор OR для таких запросов, однако есть способы выразить такие запросы.
Используйте "in" или "where".
Это будет что-то вроде этого:
db.mycollection.find( { $where : function() {
return ( this.startTime < Now() && this.expireTime > Now() || this.expireTime == null ); } } );
Ответ 4
Использование запроса $where будет медленным, отчасти потому, что он не может использовать индексы. Для такого рода проблем я думаю, что было бы лучше сохранить высокое значение для поля "expires", которое, естественно, всегда будет больше, чем Now(). Вы можете либо хранить очень высокую дату в миллионы лет в будущем, либо использовать тип "seporate", чтобы никогда не указывать. Порядок сортировки кросс-типа определяется http://www.mongodb.org/display/DOCS/Compare+Order+for+Types. Пустое Regex или MaxKey (если вы его поддерживаете) являются хорошим выбором.
Ответ 5
db.Lead.find(
{"name": {'$regex' : '.*' + "Ravi" + '.*'}},
{
"$or": [{
'added_by':"[email protected]"
}, {
'added_by':"[email protected]"
}]
}
);