【问题标题】:MongoDB - MySQL SUM (CASE WHEN) Equivalent?MongoDB - MySQL SUM(CASE WHEN)等效?
【发布时间】:2012-01-20 17:57:21
【问题描述】:

我正在尝试使用 Mongo 进行一些测试,我发现了一些与 Mongo 等效的更简单的 MySQL 查询。

我有一个更复杂的查询,我需要帮助...

SELECT DISTINCT dims_user,
    COUNT(DISTINCT asset_name) AS asset_count,
    COUNT(DISTINCT system_name) AS station_count,
    SUM(CASE WHEN details ='viewed' then 1 Else 0 end) AS viewed_count,
    SUM(CASE WHEN details Like 'Viewed Web%' then 1 Else 0 end) AS Web_count,
    SUM(CASE WHEN details = 'ThumbView' then 1 Else 0 end) AS ThumbView_count,
    SUM(CASE WHEN details Like 'Exported%' then 1 Else 0 end) AS Exported_count,
    SUM(CASE WHEN details Like '%Print%' then 1 Else 0 end) AS Printed_count
FROM asset_log GROUP BY dims_user;

【问题讨论】:

  • 呃...这不是很好的关系实践...details 列中的数据应该被规范化 - NoSQL 数据库设计也是如此,column:action =(view|web| thumb|export|print),然后您只需按操作切换到一个组。
  • 它是一堆日志文件,我刚刚得到了 3200 万条记录
  • 然后ETL它一次(如果它是静态的 - 或者建立一个用于重复加载的加载/转换过程),以便它被规范化。它将大大简化您尝试做的事情。
  • 除非您预处理数据以允许简单查询,否则您可能必须使用 map reduce(求和、计数、分组)来完成此操作

标签: mongodb sum


【解决方案1】:

我同意 Rudu 的观点,因为您应该尝试将细节分解为 mongo 文档的键。

文档可能包含这样的对象:

details:
{
  viewed: true
  thumb_view: true
  web_viewed: false
  exported: true
  ...
}

如果不重构数据,查询将需要无根正则表达式,无法使用 MongoDB 的索引功能。

但是,无论您是否决定这样做,您都需要为此使用 map reduce。您可以在映射期间发出包含详细信息的项目(通过使用正则表达式处理它们或简单地以重组形式发出键)并在 reduce 阶段对它们求和。

您可以在docs了解更多信息

【讨论】:

    【解决方案2】:

    查看此链接,它可能会有所帮助:

    http://www.kchodorow.com/blog/2011/12/09/sql-to-mongodb-an-updated-mapping/

    它解释了如何分解 SQL CASE WHEN 语句并用新的聚合管道语法替换每条 SQL。以下是您声明中第一种情况的示例:

    {
      $project : {
        'viewed': {
            '$cond': [ 
                {'$eq': ['$details', 'viewed'] },
                1, // if true
                0] // else
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      下面的例子可能对你有用。

      假设您有以下示例数据。

      db.sample.insert([
      {
        "_id" : 27001,
        "assigned_to" : "abc@xyz.com",
        "priority" : "High"
      }
      ,{
        "_id" : 27002,
        "assigned_to" : "jkdj@xyz.com",
        "priority" : "Low"
      },
      {
        "_id" : 27003,
        "assigned_to" : "abc@xyz.com",
        "priority" : "High"
      }
      ]);
      

      使用下面的聚合查询来获取

      1.总数

      2. 计算 assigend_to 是“abc@xyz.com”的地方

      3.优先级为“高”的计数

      db.sample.aggregate({$group:{
                                       _id: 0,total:{$sum:1},
                                      'assigned_to' : { $sum : { $cond: [ {  $eq: [ '$assigned_to' , 'abc@xyz.com' ] }, 1, 0 ] } },
                                      'hight_priority' : { $sum : { $cond: [ {  $eq: [ '$priority' , 'High' ] }, 1, 0 ] } }
                                    } 
                              } 
                            );
      

      你会得到预期的结果

      {
          "result" : [
              {
                  "_id" : 0,
                  "total" : 3,
                  "assigned_to" : 2,
                  "hight_priority" : 2
              }
          ],
          "ok" : 1
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-14
        • 2014-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多