首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从MongoDB中的一个查询中获取多个字段计数?

从MongoDB中的一个查询中获取多个字段计数?
EN

Stack Overflow用户
提问于 2014-06-05 15:51:09
回答 1查看 2.3K关注 0票数 1

我收集了一系列事件,其结构如下:

代码语言:javascript
运行
复制
{
    "_id" : ObjectId("537b3ff288f4ca2f471afcae"),
    "Name" : "PREMISES MAP DELETED",
    "ScreenName" : "AccessPointActivity",
    "Timestamp" : NumberLong("1392113758000"),
    "EventParams" : "null",
    "TracInfo" : {
            "ApplicationId" : "fa41f204bfc711e3b9f9c8cbb8c502c4",
            "DeviceId" : "2_1VafJVPu4yfdbMWO1XGROjK6iQZhq4hAVCQL837W",
            "UserId" : "pawan",
            "SessionId" : "a8UHE16mowNwNGyuLXbW",
            "WiFiAP" : "null",
            "WiFiStrength" : 0,
            "BluetoothID" : "null",
            "BluetoothStrength" : 0,
            "NetworkType" : "null",
            "NetworkSubType" : "null",
            "NetworkCarrier" : "Idea",
            "Age" : 43,
            "Gender" : "Female",
            "OSVersion" : "16",
            "Manufacturer" : "samsung",
            "Resolution" : "600*976",
            "Platform" : "Android",
            "Latitude" : 40.42,
            "Longitude" : -74,
            "City" : "Monmouth County",
            "CityLowerCase" : "monmouth county",
            "Country" : "United States",
            "CountryLowerCase" : "united states",
            "Region" : "New Jersey",
            "RegionLowerCase" : "new jersey",
            "Time_zone" : "null",
            "PinCode" : "07732",
            "Locale" : ", Paradise Trailer Park",
            "Accuracy" : 0,
            "Timestamp" : NumberLong("1392113758000")
    }
}

它们是在不同屏幕上的许多事件。

我的预期产出如下:

代码语言:javascript
运行
复制
{
    ApplicationId:"fa41f204bfc711e3b9f9c8cbb8c502c4",
    EventName:"PREMISES MAP DELETED",
    Eventcount:300, 
    ScreenviewCount:20,
    DeviceCount:10, 
    UserCount:3 
}

EventCount :是EventName计数

ScreenviewCount :它是每个会话不同的screenName计数

DeviceCount :它是不同deviceId的计数

UserCount :它是不同userCount的计数

它们将是多屏幕上的多个事件(ScreenName)。

目前,我正在使用以下方法:

  1. 使用聚合获取每个事件的名称,并将其计算为: { ApplicationId:"fa41f204bfc711e3b9f9c8cbb8c502c4",EventName:“已删除的房地地图”} EventCount:300}
  2. 对于上述聚合结果中的每个事件名,我在while循环中调用以下查询,直到聚合输出有文档为止:

( a)使用eventName与屏幕视图计数的聚合输出(在事件集合上)进行不同的查询。

( b)不同的查询eventName与设备计数的聚合输出(在事件集合上)。

c)将查询eventName与用于用户计数的聚合输出(在事件集合上)区分开来。

问题在于它的速度慢,因为它对每个聚合输出结果都有3个不同的查询。

是他们在单一聚合调用或其他什么情况下做这件事的任何方法。

提前谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-06 01:30:45

这里您似乎忽略的一般情况是,要在“事件”总计下获取文档中各个字段的“不同”值,可以使用$addToSet运算符。

根据定义,"set“的所有值都是”唯一/不同的“,因此您只想将所有可能的值保存在分组级别的"set”中,然后得到所产生的数组的“大小”,这正是$size操作符在MongoDB 2.6中引入的。

代码语言:javascript
运行
复制
db.collection.aggregate([
    { "$group": {
        "_id": {
            "ApplicationId": "$TracInfo.ApplicationId",
            "EventName": "$Name",
        },
        "oScreenViewCount": { 
            "$addToSet": {
                "ScreenName": "$ScreenName",
                "SessionId": "$TracInfo.SessionId",
            }
        },
        "oDeviceCount": { "$addToSet": "$TracInfo.DeviceId" },
        "oUserCount": { "$addToSet": "$TracInfo.UserId" },
        "oEventcount": { "$sum": 1 }
    }},
    { "$project": {
        "_id": 0,
        "ApplicationId": "$_id.ApplicationId",
        "EventName": "$_id.EventName",
        "EventCount": "$oEventCount",
        "ScreenViewCount": { "$size": "$oScreenViewCount" },
        "DeviceCount": { "$size": "$oDeviceCount" },
        "UserCount": { "$size": "$oUserCount" }
    }}
])

pre MongoDB 2.6版本需要做更多的工作,使用$unwind$group来计数数组:

代码语言:javascript
运行
复制
db.collection.aggregate([
    { "$group": {
        "_id": {
            "ApplicationId": "$TracInfo.ApplicationId",
            "EventName": "$Name",
        },
        "oScreenviewCount": { 
            "$addToSet": {
                "ScreenName": "$ScreenName",
                "SessionId": "$TracInfo.SessionId",
            }
        },
        "oDeviceCount": { "$addToSet": "$TracInfo.DeviceId" },
        "oUserCount": { "$addToSet": "$TracInfo.UserId" },
        "oEventcount": { "$sum": 1 }
    }},
    { "$unwind": "$oScreeenviewCount" },
    { "$group": {
        "_id": "$_id",
        "oScreenviewCount": { "$sum": 1 },
        "oDeviceCount": { "$first": "$oDeviceCount" },
        "oUserCount": { "$first": "$oUserCount" },
        "oEventcount": { "$first": "$oEventCount" }
    }},
    { "$unwind": "$oDeviceCount" },
    { "$group": {
        "_id": "$_id",
        "oScreenviewCount": { "$first": "$oScreenViewCount" },
        "oDeviceCount": { "$sum": "$oDeviceCount" },
        "oUserCount": { "$first": "$oUserCount" },
        "oEventcount": { "$first": "$oEventCount" }
    }},
    { "$unwind": "$oUserCount" },
    { "$group": {
        "_id": "$_id",
        "oScreenviewCount": { "$first": "$oScreenViewCount" },
        "oDeviceCount": { "$first": "$oDeviceCount" },
        "oUserCount": { "$sum": "$oUserCount" },
        "oEventcount": { "$first": "$oEventCount" }
    }},
    { "$project": {
        "_id": 0,
        "ApplicationId": "$_id.ApplicationId",
        "EventName": "$_id.EventName",
        "EventCount": "$oEventCount",
        "ScreenViewCount": "$oScreenViewCount",
        "DeviceCount": "$oDeviceCount",
        "UserCount": "$oUserCount"
    }}

])

第二个清单中$project的结束用法和"o“前缀名称的所有一般用法实际上只是为了在结尾处显示结果,并确保输出字段的顺序与示例结果中的相同。

作为一般的免责声明,您的问题缺乏信息来确定用于这些总数的确切字段或组合,但是原则和方法是合理的,并且应该足够接近相同的实现。

因此,从本质上说,您是通过对字段或组合使用$addToSet来获得“组”中的“不同”值的,然后您将以任何可用的方式确定这些“集合”的“计数”。

比在客户端代码中发出许多查询和合并结果要好得多。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24064723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档