Мне нужно получить список недельных диапазонов для всех записей в моем MongoDB. Когда я нажимаю на недельный диапазон, он будет отображать только записи для этого диапазона. Нажатие на диапазон недель отправляет идентификатор недели (скажем, 42
, то есть 42-я неделя вне 2015 года), он должен получить эти результаты.Получить все объекты за номер недели
Вопрос: Как я могу запросить набор записей с указанием номера недели и года? Это должно работать, не так ли?
SCHEMA:
var orderSchema = mongoose.Schema({
date: Date, //ISO date
request: {
headers : {
...
Первый: Получить все идентификаторы неделю для всех объектов:
var query = Order.aggregate(
[
{
$project:
{
week:
{
$week: '$date'
}
}
},
{
$group:
{
_id: null,
distinctDate:
{
$addToSet:
{
week: '$week'
}
}
}
}
]
);
Результат:
distinctDate: Array[35]
0: Object
week: 40
1: Object
week: 37
...
Преобразовать в диапазонах недели, используя MomentJS
и дисплей:
data.forEach(function(v, k) {
$scope.weekRanges.push(getWeekRange(v.week));
});
function getWeekRange(weekNum) {
var monday = moment().day("Monday").isoWeek(weekNum).format('MM-DD-YYYY');
var sunday = moment().day("Sunday").isoWeek(weekNum).format('MM-DD-YYYY');
...
Выход:
Week
10-12-2015 to 10-18-2015 //week ID 42
10-05-2015 to 10-11-2015 //week ID 41
09-28-2015 to 10-04-2015 ...
...
Второе: Нажмите на неделю диапазоне и получить объекты в неделю ID:
var year = 2015;
var weekID = weekParamID; //42
if (!Order) {
Order = mongoose.model('Order', orderSchema());
}
var query = Order.aggregate(
{
$project:
{
cust_ID : '$request.headers.custID',
cost : '$response.body.pricing.cost',
year :
{
$year: '$date'
},
month :
{
$month: '$date'
},
week:
{
$week: '$date'
},
day:
{
$dayOfMonth: '$date'
}
}
},
{
$match:
{
year : year, //2015
week : weekID //42
}
}
);
И если я нажимаю на неделю Range 10-12-2015 to 10-18-2015
(неделя ID 42), я получаю результаты с датами вне диапазона (10-19-2015):
10-19-2015 Order info
10-18-2015 Order info
10-19-2015 Order info
Использование MongoDB командной строки:
db.mycollection.aggregate({ $project: { week: { $week: '$date' }, day: { $dayOfMonth: '$date' } } }, { $match: { week: 42 } }
Результаты:
{ "_id" : "1bd482f6759b", "week" : 42, "day" : 19 } //shouldn't exceed week range
{ "_id" : "b3d38759", "week" : 42, "day" : 19 }
EDIT: Обновление
Таким образом, существует несоответствие с неделями ISO MongoDB (начинается в воскресенье) и Moment JS ISO (начинается в понедельник).
This SO post предлагает вычитание даты из запроса, поэтому дата Монго начинается в понедельник:
{
$project:
{
week: { $week: [ "$datetime" ] },
dayOfWeek:{$dayOfWeek:["$datetime"]}}
},
{
$project:
{
week:{$cond:[{$eq:["$dayOfWeek",1]},{$subtract:["$week",1]},'$week']}
}
}
Я реализовал это с моим запросом, но теперь он не возвращает два поля, которые мне нужно:
cust_ID : '$request.headers.custID',
cost : '$response.body.pricing.cost'
Запрос:
db.mycollection.aggregate(
{
$project:
{
cust_ID : '$request.headers.custID',
cost : '$response.body.pricing.cost',
week:
{
$week: ['$date']
},
dayOfWeek:
{
$dayOfWeek: ['$date']
}
}
},
{
$project:
{
week: {
$cond: [
{
$eq: [
"$dayOfWeek", 1
]
},
{
$subtract: [
"$week", 1
]
}, '$week'
]
}
}
},
{
$match:
{
week : 42
}
}
);
Результатов:
{ "_id" : "387e2", "week" : 42 }
{ "_id" : "ef269f6341", "week" : 42 }
{ "_id" : "17482f6759b", "week" : 42 }
{ "_id" : "7123d38759", "week" : 42 }
{ "_id" : "ff89b1fb", "week" : 42 }
Это не возвращает fieldsets я, указанный в $ проекте
Вам нужно включить их снова во второй проект. Например. стоимость: «$ cost» – sheilak
@sheilak, спасибо. Таким образом, mongodb $ cond fix не работает. Я возвращаю $ dayOfMonth, чтобы показать, в какой день месяца был размещен заказ obj, но его пока еще показываются дни (т.е. 10/19/2015 или даже 10/20/2015), которые находятся за пределами диапазона 10/12/2015 - 10/18/2015 – Growler
Обновлен мой ответ. Ответ, который вы связали с конвертированием на неделю с начала недели, но не на стандартную неделю ISO. Стандартная неделя ISO отличается от MongoDB тем, как она определяет неделю 1 в начале года. Извините, у меня нет решения, но, надеюсь, несколько указателей, чтобы приблизиться. – sheilak