Как указать ключевую функцию для групповой агрегации

Я хотел бы агрегировать по UserAgent:

db.reports.aggregate(
    {
        $group: {
            _id: '$UserAgent',
            docsPerUserAgent: {
                $sum : 1
            }
        }
    }
)

Приведенный выше запрос будет учитывать всю строку UserAgent. Что я хотел бы сделать, так это подсчитать те, которые содержат Android (вариант A), iPhone/iPad (вариант B) и остальные (вариант C). Как я могу предоставить функцию keyf в структуру агрегации (что-то похожее на это - Как сгруппировать, указав функцию для получения ключа? но в контексте агрегирующей структуры)?


person BreakPhreak    schedule 18.03.2013    source источник
comment
В настоящее время нет проекции для взятия части строки для группировки, за исключением substr, которая не будет делать то, что вы ищете. Обычно лучший способ сделать это — сохранить пользовательский агент в частях, которые вам нужно сгруппировать.   -  person Sammaye    schedule 18.03.2013
comment
если да, то почему бы не поделиться им в качестве ответа (я одобрю его)?   -  person BreakPhreak    schedule 18.03.2013
comment
если вы предоставили пример документа, это может помочь предложить другой способ достижения того же самого.   -  person Asya Kamsky    schedule 18.03.2013
comment
UserAgent — это поле, которое может содержать Android, iPhone*/*iPad и т. д. Я хотел бы group by использовать эту проекцию.   -  person BreakPhreak    schedule 18.03.2013


Ответы (1)


На данный момент нет ничего, что позволяло бы вам делать что-то вроде:

db.col.aggregate([
    {$project: {userAgentType: {$extract: /(Android|iPhone/iPad)/}}},
    {$group: on_userAgentType}
]);

Возможно, эта функция уже есть в JIRA, но я не сразу ее нашел.

Вместо этого одним из лучших способов сделать это было бы разделить «интересные» части строки пользовательского агента на отдельные поля, чтобы вы могли сгруппировать что-то вроде userAgent.agentType, которое представляет либо android, либо ipad, либо iphone. Не только это, но вы также можете использовать это для создания $match заранее, что должно означать, что вы можете использовать индекс в этом поле, что в целом сделает вашу агрегацию намного более производительной.

person Sammaye    schedule 18.03.2013
comment
только один вопрос: что за substr вы упомянули в комментариях? - person BreakPhreak; 18.03.2013
comment
@BreakPhreak docs.mongodb.org/manual/reference/aggregation/#_S_substr позволяет вам в основном делать то же самое, что substr делает в большинстве языков, таких как PHP, благодаря чему вы можете разделить поле документа, пропустив, скажем, первый символ значения и остановив 3 символа позже, т.е. в PHP substr('hello world', 1, 3) будет вернуть ello - person Sammaye; 18.03.2013
comment
обновленная ссылка на документы функции substr docs.mongodb.com/manual/reference/ оператор/агрегация/substr - person avck; 06.09.2016