2012-11-04 179 views
6

我保存我们的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"; 
... 

我想它会是这样的:(由“keyf”属性设置为自定义的JS功能

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

我知道如何使用的map-reduce做到这一点实现上述逻辑),但现在试图使用new aggregation framework来执行此操作。我试图使用expression operators来实现逻辑,但到目前为止无法实现它的工作。任何帮助/建议将不胜感激!

回答

0

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

首先,$cond运营商在$project让你实现,如果然后其他逻辑。

$cond:采用三个元件,第一布尔表达式,第二阵列和第三是值以用于字段值 - 如果布尔表达式为真,则它使用第二元件,用于数值,如果不是则第三元件。

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

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

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

+0

感谢您的答复。当我意识到无法使用支持的字符串运算符检查字符串模式的存在时,您的建议是我尝试的第一件事,并迅速遇到了死胡同。我需要像indexOf()这样的东西来查找url中的某些模式。 – Edenbauer

+0

哪里可以在“url”中出现子字符串?在您最初编写文档时存储是否可行? –

+0

我有类似的情况。我有两个字段A和B,它们在文档中的存在是相互排斥的。当A存在时,我必须由A分组,当B存在时按B分组,但是看起来您不能在$ project中拥有$ cond ..我尝试用两种方式编写$ project: {$ project:{MyKey {$ cond:[{$ exists:[“$ A”,true]},“$ A”,“$ B”]}}} {$ project:{MyKey:{$ cond:[{ A“:{$ exists:true}},”$ A“,”$ B“]}}} 但是我不断收到错误:{ ”errmsg“:”exception:invalid operator'$ exists' “code”:15999, “ok”:0 } ......也许这只是一个令人讨厌的语法问题:( –

1

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

研究了几个星期后,我的决定是在我的原始MongoDB模式中添加一个计算字段,就像@ asya-kamsky在他的一个评论中提出的那样。这并不理想,因为每当计算字段的逻辑发生变化时,我将不得不进行批量更新来更新我的集合中的所有文档,但它要么是重写我的代码以使用MapReduce。我现在选择了前者。在看MongoDB的吉拉板,这样看来,很多人都问了更多样化的运营商加入了$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