MongoDB聚合$项目

时间:2012-11-04 22:02:32

标签: mongodb aggregation-framework

我将我们的Web服务器日志存储在MongoDB中,模式类似于以下内容:

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

在尝试通过聚合管道传递集合之前,我尝试使用$project运算符重新整形此架构。基本上,我需要添加一个名为“type”的新字段,稍后将用于执行group-by。新领域的逻辑非常简单。

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函数)来执行此操作,但现在正尝试使用new aggregation framework来执行此操作。我尝试使用expression operators实现逻辑,但到目前为止无法使其工作。任何帮助/建议将不胜感激!

2 个答案:

答案 0 :(得分:1)

我正在分享我的“解决方案”,以防其他人遇到像我一样的需求。

经过几周的研究,@ asya-kamsky在他的一条评论中建议,我决定在我原来的MongoDB模式中添加一个计算字段。这并不理想,因为每当计算字段的逻辑发生变化时,我都必须进行批量更新来更新我的集合中的所有文档,但它要么是重写我的代码要么使用MapReduce。我现在选择了前者。在查看MongoDB Jira板时,似乎很多人要求为$project运算符添加更多不同的运算符,我当然希望MongoDB开发团队能够尽快添加它们

Operator for splitting string based on a separator.

New projection operator $elemMatch

Allow $slice operator in $project

add a $inOrder operator to $project

答案 1 :(得分:0)

您需要使用多个运算符和表达式的组合。

首先,$cond中的$project运算符允许您实现if then else逻辑。

$cond:取三个元素的数组,第一个是布尔表达式,第二个和第三个是用于字段值的值 - 如果布尔表达式为真,那么它使用第二个元素作为值,如果不是则为第三个元件。

你可以嵌套这些,这样第三个元素本身就是一个$cond表达式来获取if-then-else-if-then-etc.。

字符串操作有点尴尬,但确实有$substr可用。

如果您发布一些您尝试过的实例,我可能会发现它为什么不起作用。