【问题标题】:MongoDB combining group aggregation and strLenBytesMongoDB结合组聚合和strLenBytes
【发布时间】:2018-03-05 14:25:20
【问题描述】:

我有一个 Mongo 集合,其中包含这样的文档:

{
    "_id" : ObjectId("5a9d0d44c3a1ce5f14c6940a"),
    "topic_id" : "5a7af30613b79405643e7da1",
    "value" : "VMware Virtual Platform",
    "timestamp" : "2018-03-05 09:26:25.136546",
    "insert_ts" : "2018-03-05 09:26:25.136682",
    "inserted_by" : 1
},
{
    "_id" : ObjectId("5a9d0d44c3a1ce5f14c69409"),
    "topic_id" : "5a7af30713b79479f82b4b84",
    "value" : "VMware, Inc.",
    "timestamp" : "2018-03-05 09:26:25.118931",
    "insert_ts" : "2018-03-05 09:26:25.119081",
    "inserted_by" : 1
},
{
    "_id" : ObjectId("5a9d0d44c3a1ce5f14c69408"),
    "topic_id" : "5a7af30713b7946d6d0a8772",
    "value" : "Phoenix Technologies LTD 6.00 09/21/2015",
    "timestamp" : "2018-03-05 09:26:25.101624",
    "insert_ts" : "2018-03-05 09:26:25.101972",
    "inserted_by" : 1
}

我想从这个集合中获取一些聚合数据。我想知道最早的时间戳、文档数和所有值的总strlen,但按topic_id分组,其中document-id大于x。

在 mysql 中,我会像这样构建一个 sql:

SELECT 
    MAX(_id) as max_id,
    COUNT(*) as message_count,
    MIN(timestamp) as min_timestamp,
    LENGTH(GROUP_CONCAT(value)) as size
FROM `dev_topic_data_numeric` 
WHERE _id > 22000
GROUP BY topic_id

我如何在 MongoDB 中实现这一点?我已经尝试过构建它,如下所示:

db.getCollection('topic_data_text').aggregate(
[
    {
        "$match": 
        {
            "_id": {"$gte": ObjectId("5a9d0aefc3a1ce5f14c68c81") }
        }
    },
    {
        "$group": 
        {
            "_id": "$topic_id",
            "max_id": {"$max":"$_id"},
            "min_timestamp": {"$min": "$timestamp"},
            "message_count": {"$sum": 1},
            /*"size": {"$strLenBytes": "$value" }*/
        }
    } 
]
);

然后我取消注释 $strLenBytes 它崩溃说 strLenBytes 不是组运算符。 API of MongoDB 在这里对我没有帮助。怎么写才能得到strlen?

我的预期结果应该是这样的:

{
    "_id" : "5a7af30613b79405643e7da1",
    "max_id" : ObjectId("5a9d0d44c3a1ce5f14c6940a"),
    "min_timestamp" : "2018-03-05 09:26:25.136546",
    "message_count" : 1,
    "size" : 23,
}

我的 MongoDB 版本是 3.4.4。

【问题讨论】:

  • 你能添加预期的输出吗?
  • 你试过"size": { "$sum": {"$strLenBytes": "$value" } }吗?
  • @RahulSharma 完成。
  • @chridam 我检查了你的建议。结果错误显示“无效的运算符 $strLenBytes”
  • 我得到的最接近的结果是使用 {"$push":"$value"} ...但这并不是我想要得到的结果。

标签: mongodb aggregation-framework aggregate


【解决方案1】:

这是因为$strLenBytes 不是累加器,不像$sum$max$group 阶段累加值,因此在 $group 阶段有效的任何运算符通常都是累加器。

$strLenBytes 以 1-1 的方式将一个值转换为另一个值。这通常是 $project 阶段的运算符。

在聚合中添加 $project 阶段应该会给您所需的结果。请注意,您还需要稍微修改 $group 阶段以传递所需的值:

> db.test.aggregate([
     {
         "$match":
         {
             "_id": {"$gte": ObjectId("5a9d0aefc3a1ce5f14c68c81") }
         }
     },
     {
         "$group":
         {
             "_id": {"topic_id": "$topic_id", value: "$value"},
             "max_id": {"$max":"$_id"},
             "min_timestamp": {"$min": "$timestamp"},
             "message_count": {"$sum": 1}
         }
     },
     {
         "$project":
         {
             "_id": "$_id.topic_id",
             "max_id": "$max_id",
             "min_timestamp": "$min_timestamp",
             "message_count": "$message_count",
             size: {"$strLenBytes": "$_id.value" }
         }
     }
 ])

使用您的示例文档输出:

{
  "_id": "5a7af30613b79405643e7da1",
  "max_id": ObjectId("5a9d0d44c3a1ce5f14c6940a"),
  "min_timestamp": "2018-03-05 09:26:25.136546",
  "message_count": 1,
  "size": 23
}
{
  "_id": "5a7af30713b79479f82b4b84",
  "max_id": ObjectId("5a9d0d44c3a1ce5f14c69409"),
  "min_timestamp": "2018-03-05 09:26:25.118931",
  "message_count": 1,
  "size": 12
}
{
  "_id": "5a7af30713b7946d6d0a8772",
  "max_id": ObjectId("5a9d0d44c3a1ce5f14c69408"),
  "min_timestamp": "2018-03-05 09:26:25.101624",
  "message_count": 1,
  "size": 40
}

【讨论】:

  • 谢谢。这解决了我的问题,也帮助我更多地理解了项目阶段。在我看来,该文档缺乏对其用途和如何使用它的更深入的解释。
【解决方案2】:

在测试了@kevin-adistambha 的答案并进行了一些进一步的实验之后,我找到了另一种方法来实现我想要的结果——也许它有更好的性能——但这需要更多的测试来确定。

db.getCollection('topic_data_text').aggregate(
[
    {
        "$match": 
        {
            "_id":  {"$gt": ObjectId("5a9f9d8bd5de3ac75f8cc269") }
        }
    },
    {
        "$group": 
        {
            "_id": "$topic_id",
            "max_id": {"$max":"$_id"},
            "min_timestamp": {"$min": "$timestamp"},
            "message_count": {"$sum": 1},
            "size": {"$sum": {"$strLenBytes": "$value"}}
        }
    }
]
);

【讨论】:

猜你喜欢
  • 2015-12-28
  • 2019-03-13
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多