mongo-aggregation: применить группировку регулярных выражений, обработку строк в $project

Я хотел бы применить некоторые простые манипуляции со строками при выполнении $project, можно ли применить что-то вроде следующей функции к $project? :

var themeIdFromZipUrl = function(zipUrl){
    return zipUrl.match(/.*\/(T\d+)\/.*/)[1]
};

Я использую следующий запрос:

db.clientRequest.aggregate(
{
$match: {
  "l": {$regex: ".*zip"},
  "t": { "$gte": new Date('1/SEP/2013'),
                    "$lte": new Date('7/OCT/2013')
                    }
  }
},
{
  $project: {"theme_url" : "$l", "_id": 0, "time": "$t"}
},
{
  $group: {   _id: {
                      theme_url: "$theme_url",
                      day: {
                              "day": {$dayOfMonth : "$time"},
                              "month": {$month: "$time"},
                              "year": {$year: "$time"}
                            },
              },
              count: {$sum:1}
  }
}

)

Это возвращает следующее:

        {
        "_id" : {
            "theme_url" : "content/theme/T70/zip",
            "day" : {
                "day" : 13,
                "month" : 9,
                "year" : 2013
            }
        },
        "count" : 2
    }

Могу ли я применить указанную выше функцию к полю theme_url и превратить ее в theme_id? Я немного взглянул на Map-Reduce, но не уверен, что это слишком сложно для такого простого случая.

Спасибо,

Амит.


person amit    schedule 29.10.2013    source источник
comment
в настоящее время нет поддержки для выполнения этого напрямую, но есть уродливый способ сделать это с помощью структуры агрегации (включает сравнение символов, чтобы выяснить, где вырезать строку).   -  person Asya Kamsky    schedule 11.01.2014


Ответы (1)


В настоящее время нет способа сделать это с помощью Aggregation Framework.

Вы можете сделать это с помощью MapReduce, но это, вероятно, замедлит всю работу (если объем данных велик).

Если это последний шаг агрегации, вы также можете сделать это на стороне клиента после завершения агрегации. например в оболочке Монго:

var aggregationResults = col.aggregate([ /* aggregation pipeline here */]);
aggregationResults.results.forEach(function(x) { 
  x._id.theme_id = themeIdFromUrl(x._id.themeUrl);
});

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

Вообще говоря, если ваши данные содержат theme_url, а theme_id закодирован в URL-адресе, может иметь смысл хранить его в отдельном поле. Mongo — не очень хороший инструмент для работы с текстом.

person Avish    schedule 28.01.2014