Совокупный проект MongoDB $

Я храню журналы нашего веб-сервера в MongoDB, и схема выглядит примерно так:

[
  {  
    "_id" : 12345,
    "url" : "http://www.mydomain.com/xyz/abc.html",
    ....
  },
  ....
]

Я пытаюсь использовать оператор $project, чтобы немного изменить эту схему перед Я начинаю передавать свою коллекцию через конвейер агрегации. По сути, мне нужно добавить новое поле под названием «тип», которое позже будет использоваться для группировки. Логика нового поля довольно проста.

if "url" contains "pattern_A" then set "type" = "sales lead";
else if "url" contains "pattern_B" then set "type" = "existing client";
...

Я думаю, что это должно быть что-то вроде этого:

db.weblog.aggregate(
  { 
    $project : {
      type : { /* how to implement the logic??? */ }
    }
  }
);

Я знаю, как это сделать с помощью map-reduce (путем установки атрибута «keyf» для пользовательской функции JS, которая реализует описанную выше логику), но теперь я пытаюсь использовать новая структура агрегации, чтобы сделать это. Я попытался реализовать логику с помощью операторов выражений, но так далеко не мог заставить его работать. Любая помощь/предложение будет принята с благодарностью!


person Edenbauer    schedule 04.11.2012    source источник


Ответы (2)


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

После нескольких недель исследований, как предложил @asya-kamsky в одном из своих комментариев, я решил добавить вычисляемое поле в исходную схему MongoDB. Это не идеально, потому что всякий раз, когда изменяется логика для вычисляемого поля, мне приходилось выполнять массовые обновления, чтобы обновить все документы в моей коллекции, но либо так, либо переписывать мой код для использования MapReduce. Я пока выбрал первое. Глядя на доску MongoDB Jira, может показаться, что многие люди просили добавить более разнообразных операторов для $project, и я очень надеюсь, что команда разработчиков MongoDB добавит их раньше, чем позже.

Оператор для разделения строки на основе разделителя.

Новый оператор проекции $elemMatch

Разрешить оператор $slice в $project

добавить оператор $inOrder в $project

person Edenbauer    schedule 03.01.2013

Вам нужно использовать комбинацию нескольких операторов и выражений.

во-первых, оператор $cond в $project позволяет реализовать логику if then else.

$cond : принимает массив из трех элементов, первый - логическое выражение, второй и третий - значения, используемые для значения поля - если логическое выражение истинно, то он использует второй элемент для значения, если нет, то третий элемент.

вы можете вложить их так, чтобы третий элемент сам был выражением $cond для получения if-then-else-if-then-etc.

манипуляции со строками немного неудобны, но у вас есть $substr.

Если вы опубликуете несколько примеров того, что именно вы пробовали, я смогу понять, почему это не сработало.

person Asya Kamsky    schedule 05.11.2012
comment
Спасибо за ваш ответ. Ваше предложение было самым первым, что я попытался сделать, и быстро зашел в тупик, когда понял, что не могу проверить существование строкового шаблона с помощью поддерживаемых строковых операторов. Мне нужно что-то вроде indexOf(), чтобы искать определенные шаблоны в URL-адресе. - person Edenbauer; 06.11.2012
comment
где может быть подстрока в URL? Можно ли что-то сохранить во время первоначального написания документа? - person Asya Kamsky; 06.11.2012
comment
У меня аналогичная ситуация. У меня есть два поля A и B, и их существование в документе является взаимоисключающим. Я должен сгруппировать по A, когда существует A, и сгруппировать по B, когда существует B, но похоже, что вы не можете иметь $cond в $project.. Я пытался написать $project двумя способами: {$project: {MyKey: {$cond: [{$exists: [$A, true]}, $A, $B]}}} и {$project: {MyKey: {$cond: [{A: {$exists:true}}, $A, $B]}}} Но я продолжаю получать сообщение об ошибке: { errmsg : исключение: недопустимый оператор '$exists', код: 15999, ok: 0 } ... Возможно, это просто раздражающий синтаксис :( - person Aafreen Sheikh; 03.01.2013
comment
@AafreenSheikh то, что вы описываете, выполнимо - вы, вероятно, хотите начать еще один вопрос со своей проблемой, а не пытаться объяснить в комментариях. - person Asya Kamsky; 04.01.2013
comment
@AsyaKamsky Здесь задан вопрос: stackoverflow.com/questions /14213636/ - person Aafreen Sheikh; 08.01.2013