【问题标题】:MongoDB Aggregate $projectMongoDB 聚合 $project
【发布时间】:2012-10-24 18:35:48
【问题描述】:

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

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

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

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 来实现逻辑,但到目前为止还不能让它工作。任何帮助/建议将不胜感激!

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

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

    在研究了几周后,正如@asya-kamsky 在他的一个 cmets 中所建议的那样,我决定在我的原始 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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      如果您发布一些您尝试过的具体示例,我可能会发现它不起作用的原因。

      【讨论】:

      • 感谢您的回复。您的建议是我尝试的第一件事,当我意识到我无法使用支持的字符串运算符检查字符串模式的存在时,很快就陷入了死胡同。我需要 indexOf() 之类的东西来查找 url 中的某些模式。
      • 子字符串可以出现在“url”的什么地方?在您最初编写文档时存储是否可行?
      • 我也有类似的情况。我有两个字段 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 } ...也许这只是一个烦人的语法问题:(
      • @AafreenSheikh 你所描述的是可行的——你可能想从你的问题开始另一个问题,而不是试图在 cmets 中解释。
      • @AsyaKamsky 在这里提问:stackoverflow.com/questions/14213636/…
      猜你喜欢
      • 2013-03-10
      • 1970-01-01
      • 2015-07-04
      • 2015-12-03
      • 2019-09-29
      • 1970-01-01
      • 2018-03-27
      • 2021-04-11
      • 1970-01-01
      相关资源
      最近更新 更多