Вопрос

Итак, у меня есть встроенный документ, который отслеживает членство в группах.Каждый внедренный документ имеет идентификатор, указывающий на группу в другой коллекции, дату начала и дату начала. необязательный Дата истечения срока годности.

Я хочу запросить текущих членов группы.«Текущее» означает, что время начала меньше текущего времени, а время истечения больше текущего времени ИЛИ равно нулю.

Этот условный запрос полностью меня блокирует.Я мог бы сделать это, выполнив два запроса и объединив результаты, но это кажется некрасивым и требует загрузки всех результатов одновременно.Или я мог бы по умолчанию установить время истечения срока действия на какую-то произвольную дату в далеком будущем, но это кажется еще более уродливым и потенциально хрупким.В SQL я бы просто выразил это с помощью «(истекает >= Now()) ИЛИ (истекает IS NULL)», но я не знаю, как это сделать в Mongo.

Есть идеи?Большое спасибо заранее.

Это было полезно?

Решение

Просто подумал, что обновлю на случай, если кто-нибудь наткнется на эту страницу в будущем.Начиная с версии 1.5.3, mongo теперь поддерживает настоящий оператор $or: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or

Ваш запрос «(истечет >= Now()) OR (истечет IS NULL)» теперь может быть отображен как:

{$or: [{expires: {$gte: new Date()}}, {expires: null}]}

Другие советы

Если кому-то будет полезно, www.querymongo.com выполняет перевод между SQL и MongoDB, включая предложения OR.Это может быть очень полезно для понимания синтаксиса, если вы знаете эквивалент SQL.

В случае операторов OR это выглядит так

SQL:

SELECT * FROM collection WHERE columnA = 3 OR columnB = 'string';

МонгоБД:

db.collection.find({
    "$or": [{
        "columnA": 3
    }, {
        "columnB": "string"
    }]
});

Запрашивайте объекты в Mongo по умолчанию И выражения вместе.В настоящее время Mongo не включает оператор OR для таких запросов, однако существуют способы выразить такие запросы.

Используйте «в» или «где».

Это будет что-то вроде этого:

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"
}]
}

);

Используя $where запрос будет медленным, отчасти потому, что он не может использовать индексы.Я думаю, что для такого рода проблем было бы лучше сохранить высокое значение для поля «expires», которое, естественно, всегда будет больше, чем Now().Вы можете либо сохранить очень большую дату на миллионы лет вперед, либо использовать отдельный тип, чтобы указать «никогда».Порядок сортировки перекрестного типа определяется в здесь.

Пустое Regex или MaxKey (если ваш язык поддерживает это) являются хорошим выбором.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top