На самом деле проблема не в логической композиции. Ваш вложенный запрос $and
$or
в порядке.
Это разница между MongoDB и JavaScript при создании даты, которая сбивает вас с толку.
в Монго:
> new Date("2012-01-07T04:45:52.057Z")
ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ")
в JavaScript:
> new Date("2012-01-07T04:45:52.057Z")
Sat, 07 Jan 2012 04:45:52 GMT
Чтобы исправить это, вы должны использовать ISODate
в монго.
> ISODate('2012-01-07T04:45:52.057Z')
ISODate("2012-01-07T04:45:52.057Z")
ОБНОВЛЕНИЕ : добавить тесты:
Чтобы доказать правильность вашей логической комбинации, я написал следующие сценарии:
populate.js
: введите данные выборки:
var past = new Date('01/01/2011'),
future = new Date('01/01/2013');
var dates = [
{
num: 1
},
{
num: 2,
Date2: past
},
{
num: 3,
Date2: future
},
{
num: 4,
Date1: past,
Date2: past
},
{
num: 5,
Date1: past
},
{
num: 6,
Date1: future
}
];
dates.forEach(function(date) {
db.dates.insert(date);
});
query.js
: проверить три запроса:
function queryNum(query) {
print(db.dates.find(query).map(function(v) {
return v.num;
}));
}
var q1 = {
"$or": [{
"Date1": {
"$exists": false
}
},
{
"Date1": {
"$exists": true,
"$lte": new Date('01/01/2012')
}
}]
};
var q2 = {
"$or": [{
"Date2": {
"$exists": false
}
},
{
"Date2": {
"$exists": true,
"$lte": new Date('01/01/2012')
}
}]
};
var q3 = {
$and: [q1, q2]
};
queryNum(q1);
queryNum(q2);
queryNum(q3);
Правильно печатает:
1,2,3,4,5
2,2,4,5,6
1,2,4,5