2015-06-29 3 views
1

У меня есть следующие записи:MongoDB: любой способ использовать определенную пользователем функцию в агрегации?

{ "_id" : ObjectId("55889370ba09474fd178d8b8"), "url" : "http://stackoverflow.com/questions/ask"} 
{ "_id" : ObjectId("55889370ba09474fd178d8b4"), "url" : "http://stackoverflow.com"} 
{ "_id" : ObjectId("55889370ba09474fd178d8b2"), "url" : "http://espn.com"} 

И я хочу сделать агрегацию, чтобы получить количество каждого сайта по своему корню. В принципе, я хочу, чтобы обе первые две записи попадали под одну и ту же группу (они имеют один и тот же корень).

Я создал функцию, определенную пользователем, чтобы преобразовать url в свой корень. Моя идея состояла в том, чтобы использовать определенную пользователем функцию для первого проекта записи (изменение поля url), а затем группировки по URL-адресу. Проблема в том, что явно определенные пользователем функции не могут использоваться в агрегатах. Они могут использоваться в тех случаях, когда предложения в проекции, но прогнозы, где клаузулы не могут использоваться в агрегации.

Есть ли способ, которым я могу агрегировать, в котором я нуждаюсь?

EDIT:

Может быть сделать пример нагляднее я должен добавить, что если я, например, хотел группе корневым веб-сайт и сосчитать их я хотел бы получить что-то вроде:

{ "_id" : "http://stackoverflow.com", "count" : 2} 
{ "_id" : "http://espn.com", "count" : 1} 
+0

Вы в основном ищете ** '$ project' ** фильтр, используя **' $ regex' **, но в настоящее время структура агрегации не имеет этой функции, здесь есть открытая JIRA [* * SERVER-11947 **] (https://jira.mongodb.org/Просмотр/SERVER-11947). – chridam

+0

Значит, нет способа сделать это сейчас? Нет другой альтернативы? –

+0

Не подходит ли это http://stackoverflow.com/a/16252753/4573999? –

ответ

1

Попробуйте использование regex при сборке. Думаю, вы можете пропустить определенную пользователем функцию.

Этот question использует его, например.

В вашем конкретном случае описано обходное решение here. Не уверен, что это то, что вы хотите.

В противном случае я боюсь, что вам нужно будет уменьшить его.

+1

Не используется ли регулярное выражение в этом случае в предложении match? Я не хочу фильтровать записи. Я просто хочу преобразовать поле во время проекции, чтобы они могли попасть под один и тот же ключ во время группировки. –

+0

Правда, но я подумал, может быть, это обходное решение представляло интерес: http://stackoverflow.com/a/17493547/1566187 Можете ли вы подтвердить? В противном случае просто используйте map-reduce, я бы сказал. – Elyasin

1

Это простое решение. Пример данных:

> db.test.find() 
{ "_id" : ObjectId("559178703535798edab41c36"), "text" : "aaaasfadf" } 
{ "_id" : ObjectId("559178743535798edab41c37"), "text" : "bfasdfasdf" } 
{ "_id" : ObjectId("559178783535798edab41c38"), "text" : "aasdfsdf" } 
{ "_id" : ObjectId("5591787b3535798edab41c39"), "text" : "asdf" } 
{ "_id" : ObjectId("5591787e3535798edab41c3a"), "text" : "csfd" } 

Я хочу элементов группы, основанные на первой букве строки (вы размещаете вам функцию, которая извлекает базу URL здесь):

db.test.group({ 
    $keyf : function(doc){ 
     return { 
      key : doc.text.substring(0,1) // extract URL base here 
     } 
    }, 
    $reduce : function(curr, result){ 
     result.count++ 
    }, 
    initial : { 
     count: 0 
    } 
}) 

Результат является:

[ 
    { 
     "key" : "a", 
     "count" : 3 
    }, 
    { 
     "key" : "b", 
     "count" : 1 
    }, 
    { 
     "key" : "c", 
     "count" : 1 
    } 
] 
Смежные вопросы