Запрос MongoDB с условием «или»
Поэтому у меня есть встроенный документ, который отслеживает членство в группах. Каждый встроенный документ имеет идентификатор, указывающий на группу в другой коллекции, дату начала и дополнительную дату истечения срока действия.
Я хочу запросить для текущих членов группы. «Ток» означает, что время начала меньше текущего времени, а время истечения превышает текущее время ИЛИ null.
Этот условный запрос полностью блокирует меня. Я мог бы сделать это, выполнив два запроса и объединив результаты, но это кажется уродливым и требует загрузки во всех результатах сразу. Или я мог бы по умолчанию истекать время до какой-то произвольной даты в далеком будущем, но это кажется еще более уродливым и потенциально хрупким. В SQL я бы просто выразил это с помощью «(expires> = Now ()) OR (истекает IS NULL)» – но я не знаю, как это сделать в Mongo.
- Как я могу использовать cursor.forEach () в MongoDB с помощью Node.js?
- MongoDB: выводит 'id' вместо '_id'
- Выполнение запросов mongoose.js синхронно
- Удаление определенных элементов из массива с помощью MongoDB
- Node.js - Mongoose - проверьте, существует ли коллекция
Есть идеи? Большое спасибо заранее.
- В mongoDb, как удалить элемент массива по его индексу
- На какой уровень блокирует MongoDB запись? (или: что это означает «за соединение»,
- Удалить поле из всех элементов массива в mongodb
- Как обойти отсутствие транзакций в MongoDB?
- Узел MongoDB проверяет, действительно ли objectid
- Найти в двойном вложенном массиве MongoDB
- (MongoDB Java) $ push в массив
- Поток от указателя mongodb до express-ответа в node.js
Просто подумал, что я обновляю в случае, если кто-нибудь наткнется на эту страницу в будущем. Начиная с 1.5.3, монго теперь поддерживает реальный $ или оператор: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
Ваш запрос “(expires> = Now ()) ИЛИ (истекает IS NULL)” теперь можно отобразить как:
{$or: [{expires: {$gte: new Date()}}, {expires: null}]}
В случае, если кто-либо считает это полезным, http://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" }] });
Объекты запроса в Mongo по умолчанию и выражения вместе. В настоящее время Mongo не включает оператор OR для таких запросов, однако есть способы выразить такие запросы.
Используйте «in» или «where».
Это будет что-то вроде этого:
db.mycollection.find( { $where : function() { return ( this.startTime < Now() && this.expireTime > Now() || this.expireTime == null ); } } );
Использование запроса $ where будет медленным, отчасти потому, что он не может использовать индексы. Для такого рода проблем я думаю, что было бы лучше сохранить высокое значение для поля «expires», которое, естественно, всегда будет больше, чем Now (). Вы можете либо хранить очень высокую дату в миллионы лет в будущем, либо использовать тип «seporate», чтобы никогда не указывать. Порядок сортировки кросс-типа определяется по адресу http://www.mongodb.org/display/DOCS/Compare+Order+for+Types . Пустое Regex или MaxKey (если вы его поддерживаете) являются хорошим выбором.