2014-02-03 3 views
5

Я использую оператора $ project для извлечения части недели из Date, а затем группируюсь по неделям в конвейере агрегации.

{ $project: { 
    year: { $year: [ "$datetime" ] }, 
    week: { $week: [ "$datetime" ] }, 
    .... 
    } 
}, 
.... 
{ $group: { 
    _id: { 
     year: "$year", 
     week: "$week", 
     }, 
     ..... 
    } 
} 

Но $ неделе оператор, который я использую для этого, всегда считается воскресенье в первый день недели, и мы используем в понедельник, как первый день недели в нашем месте. Поэтому результаты, сгруппированные по неделям, всегда неверны для меня. Есть ли способ справиться с этим, или известный обходной путь?

existing request in mongo tracking system, по-видимому, не разрешен более года (действительно ли это редко нужен вариант?) Любые возможные варианты приветствуются. Может быть, есть возможность создать некоторую пользовательскую функцию в javascript и добавить/заменить ее где-нибудь?

+0

Не могли бы вы добавить некоторые данные примера, чтобы мы могли опробовать наши ответы перед публикацией. Благодарю. – Alex

ответ

7

Вы можете использовать ниже трубопровода, чтобы изменить операцию $ неделю согласно вашему требованию

[{ 
    $project: 
    { 
    week: { $week: [ "$datetime" ] }, 
    dayOfWeek:{$dayOfWeek:["$datetime"]} 
    } 
}, 
{ 
    $project: 
    { 
     week:{$cond:[{$eq:["$dayOfWeek",1]},{$subtract:["$week",1]},'$week']} 
    } 
}] 

Что она делает это, что на первом этапе он проецирует weekOfYear и DAYOFWEEK. На втором этапе он проверяет, является ли dayOfWeek воскресным, если в этом случае он изменяет неделю на неделю -1. Затем это будет работать так, как будто неделя начинается в понедельник.

+0

thx, это умный способ, и, похоже, он работает. проверит угловые шкафы, если есть –

+0

@VolodymyrMetlyakov - эй, просто интересно, проверили ли вы это для всех угловых случаев? – Ghopper21

+0

@VolodymyrMetlyakov - также, как написано, эти этапы проектирования будут отфильтровывать все остальные поля, так как другие поля должны быть явно указаны для прохождения этих этапов. – Ghopper21

0

Думаю, вам лучше справиться с этим в прикладном пространстве.

Было бы лучше сохранить запрос простым и создать метод обертки для форматирования результатов до желаемого представления.

+0

уровень приложения всегда является опцией. как и для меня, это последнее средство в случае, если не найдено подходящего решения на уровне дБ. особенно я хотел бы избежать возиться с материалами даты, если возможно –

+1

Ваш POV правильный, это последнее средство. Я просто предоставляю его в качестве альтернативы. Это может быть полезно, если ваши данные не так много, и вы хотите избежать дополнительной сложности db. – xlembouras

3

MongoDB, наконец, добавил $isoWeek и $isoWeekYear в 3.4, который начнется неделю в понедельник.

Дополнительная информация: https://docs.mongodb.com/manual/reference/operator/aggregation/isoWeek/

+0

Примечание для большинства - по состоянию на 4/24/2017, «MongoDB v3.4» по-прежнему широко не используется на облачных платформах, таких как MongoHQ ... У них есть бета-версии, которые могут быть приглашены (я был) .. ,Помните об этом, если вы используете что-то вроде Heroku или облачного хостера отдельно, вы не сможете использовать функции 3.4, возможно, несколько месяцев. –

2

Trick: просто изменить одну строку путем вычитания один день из DateTime

$project: { 
    year: { $year: [ "$datetime" ] }, 
    week: { $week: {$subtract: ["$datetime", 86400000] } }, // <--- minus 1 day (in ms). 
    .... 
    } 

Это работает на новых и старых версий Монго.

+0

это умный, если нет ловушек :) –

Смежные вопросы