首页 > 解决方案 > 从一开始就计算不同的用户数量

问题描述

我有一个 MongoDB 聚合管道,这让我很沮丧一段时间,因为它似乎永远无法准确或正确地满足我的需求。目的是从一开始就计算每个聊天机器人每天新增的唯一用户数量。

这是我的管道现在的样子。

[
            {
                "$project" : {
                    "_id" : 0,
                    "bot_id" : 1,
                    "customer_id" : 1,
                    "timestamp" : {
                        "$ifNull" : [
                            '$incoming_log.created_at', '$outcome_log.created_at'
                            ]
                        }
                    }
                },
            {
                "$project" : {
                    "customer_id" : 1,
                    "bot_id" :  1,
                    "timestamp" : {
                        "$dateFromString" : {
                            "dateString" : {
                                "$substr" : [
                                    "$timestamp", 0, 10
                                    ]
                                }
                            }
                        }
                    }
                },
            {
                "$group" : {
                    "_id" : "$customer_id",
                    "timestamp" : {
                        "$first" : "$timestamp"
                        },
                    "bot_id" : {
                        "$addToSet" : "$bot_id"
                        }
                    }
                },
            {
                "$unwind" : "$bot_id"
                },
            {
                "$group" : {
                    "_id" : {
                        "bot_id" : "$bot_id",
                        "customer_id" : "$_id"
                        },
                    "timestamp" : {
                        "$first" : "$timestamp"
                        }
                    }
                },
            {
                "$project" : {
                    "_id" : 0,
                    "timestamp" : 1,
                    "customer_id" : "$_id.customer_id",
                    "bot_id" : "$_id.bot_id"
                    }
                },
            {
                "$group" : {
                    "_id": {
                        "timestamp" : "$timestamp",
                        "bot_id" : "$bot_id"
                        },
                    "new_users" : {
                        "$sum" : 1
                        }
                    }
                },
            {
                "$project" : {
                    "_id" : 0,
                    "timestamp" : "$_id.timestamp",
                    "bot_id" : "$_id.bot_id",
                    "new_users" : 1
                    }
                }
]

一些示例数据,用于了解数据的外观......

{ 
    "mid" : "...", 
    "bot_id" : "...", 
    "bot_name" : "JOBBY", 
    "customer_id" : "U122...", 
    "incoming_log" : { 
        "created_at" : ISODate("2020-12-08T09:14:16.237Z"),
        "event_payload" : "", 
        "event_type" : "text" 
        }, 
    "outcome_log" : { 
        "created_at" : ISODate("2020-12-08T09:14:18.145Z"), 
        "distance" : 0.25, 
        "incoming_msg" : "" 
        } 
    }

我的预期结果是这样的:

{     
    "new_users" : 1187.0,     
    "timestamp" : ISODate("2021-01-27T00:00:00.000Z"),     
    "bot_id" : "5ffd......." 
},
{
    "new_users" : 1359.0,
    "timestamp" : ISODate("2021-01-27T00:00:00.000Z"),
    "bot_id" : "6def......."
}

我是否在某处使管道过于复杂?我似乎每天每个机器人都有合理数量的新用户,但出于某种原因,我的同事告诉我这个数字太高了。我需要一些提示,拜托!

标签: mongodb

解决方案


我真的不知道你在找什么。

“我们的目标是从一开始就计算每个聊天机器人每天新增的唯一用户数量。”

什么是“新的唯一用户”?“从头开始”是什么意思?您要求每天计数,但您使用{"$group": {"_id": "$customer_id", "timestamp": { "$first": "$timestamp" } } }

对我来说,你的分组没有任何意义。只有一个示例文档,几乎不可能猜出您喜欢计算什么。

关于每天的小组:我更喜欢始终使用Date值,而不是字符串。它更不容易出错。也许您必须考虑时区,因为 UTC 午夜不是您当地的午夜。当您与之合作时,Dates您可以更好地控制它。

$project当你$group事后做这些阶段是没有用的。通常你最后只有一个$project阶段。

所以,放点东西开始吧。

db.collection.aggregate([
   {
      $set: {
         day: {
            $dateToParts: {
               date: { $ifNull: ["$incoming_log.created_at", "$outcome_log.created_at"] }
            }
         }
      }
   },
   {
      $group: {
         _id: "$customer_id",
         timestamp: {$min: { $dateFromParts: { year: "$day.year", month: "$day.month", day: "$day.day" } }}
      }
   }
]);

推荐阅读