根据嵌套数组值和计数唯一

时间:2017-07-08 10:11:20

标签: mongodb mongodb-query aggregation-framework

我有一个MongoDB集合,其中包含给定格式的文档,

{
    "_id" : ObjectId("595f5661f34ae7b2adee31bc"),
    "app_userUpdatedOn" : "2017-03-09T12:01:07.615Z",
    "appId" : 31625,
    "app_lastCommunicatedAt" : "2017-03-09T12:18:53.067Z",
    "currentDate" : "2017-03-09T12:19:28.626Z",
    "objectId" : "58c14850e4b0b2406992b29e",
    "name" : "APPSESSION",
    "action" : "START",
    "installationId" : "98088f6641a0fa79",
    "userName" : "98088f6641a0fa79",
    "properties" : [
        [
            "userid",
            "98088f6641a0fa79"
        ],
        [
            "app_os_version",
            "6.0.1"
        ],
        [
            "app_installAt",
            "2017-03-09T12:01:01.307Z"
        ],
        [
            "app_model",
            "SM-J210F"
        ],
        [
            "app_lastCommunicatedAt",
            "2017-03-09T12:18:53.067Z"
        ],
        [
            "app_carrier",
            "Jio 4G"
        ],
        [
            "app_counter",
            1
        ],
        [
            "app_brand",
            "samsung"
        ],
        [
            "app_lib_version",
            "1.0"
        ],
        [
            "app_app_version",
            "3.0.2"
        ],
        [
            "app_os",
            "Android"
        ]
    ],
    "date" : "2017-03-09"
}
{
    "_id" : ObjectId("595f5661f34ae7b2adee31bd"),
    "app_userUpdatedOn" : "2017-02-05T07:38:32.866Z",
    "appId" : 31625,
    "app_lastCommunicatedAt" : "2017-03-09T08:09:05.342Z",
    "currentDate" : "2017-03-09T12:19:28.806Z",
    "objectId" : "58c14850e4b06ec88ecaa9c6",
    "name" : "APPINSTALL",
    "action" : "START",
    "installationId" : "eef436554fbdf4ac",
    "userName" : "eef436554fbdf4ac",
    "properties" : [
        [
            "userid",
            "eef436554fbdf4ac"
        ],
        [
            "app_os_version",
            "5.1"
        ],
        [
            "app_installAt",
            "2017-02-05T11:20:49.809Z"
        ],
        [
            "app_model",
            "Micromax Q465"
        ],
        [
            "app_lastCommunicatedAt",
            "2017-03-09T08:09:05.342Z"
        ],
        [
            "app_carrier",
            "JIO 4G"
        ],
        [
            "app_counter",
            1
        ],
        [
            "app_brand",
            "Micromax"
        ],
        [
            "app_lib_version",
            "1.0"
        ],
        [
            "app_app_version",
            "3.0.2"
        ],
        [
            "app_os",
            "Android"
        ]
    ],
    "date" : "2017-03-09"
}

我想获取 currentDate 介于其中的文档的计数和唯一计数, startDate endDate ,名称为x(例如.APPSESSION),包含多个属性嵌套数组(如[“app_installAt”,“这可以是任何值而不是null ”],[“app_model”,“这可以是任何值而不是null “],依此类推...),分组依据 userName

以前我创建了一个查询,其中嵌套数组两个元素都是已知的,如下所示

db.testing.aggregate(
      [
            {$match: {currentDate: {$gte:"2017-03-01T00:00:00.000Z", $lt:"2017-03-02T00:00:00.000Z"},name:"INSTALL"}},
            {$match: {properties: ["app_os_version","4.4.2"]}},
            {$match: {properties: ["app_carrier","telenor"]}},
            {$match: {properties: ["app_brand","Micromax"]}},
            {$group: {_id: "$userName"}},
            {$count: "uniqueCount"}
      ]
);

但是我无法找到我只知道属性数据嵌套数组的第0个索引的数据。

请帮助。

先谢谢.... :)

1 个答案:

答案 0 :(得分:1)

对此的查询基本上是使用$all来匹配数组中的多个条件,然后使用$elemMatch$eq来匹配各个数组元素。

例如,为了“仅”匹配和计算您问题中提供的第一个文档,参数将是:

db.testing.find({
  "currentDate": { 
    "$gte": "2017-03-09T00:00:00.000Z",
    "$lt": "2017-03-10T00:00:00.000Z"
  },
  "properties": {
    "$all": [
      { "$elemMatch": { "$eq": ["app_os_version","6.0.1"] } },
      { "$elemMatch": { "$eq": ["app_carrier", "Jio 4G"] } },
      { "$elemMatch": { "$eq": ["app_brand", "samsung"] } }
    ]   
  }
})

使用.aggregate(),然后将整个查询放入单个$match阶段,如下所示:

db.testing.aggregate([
  { "$match": {
    "currentDate": { 
      "$gte": "2017-03-09T00:00:00.000Z",
      "$lt": "2017-03-10T00:00:00.000Z"
    },
    "properties": {
      "$all": [
        { "$elemMatch": { "$eq": ["app_os_version","6.0.1"] } },
        { "$elemMatch": { "$eq": ["app_carrier", "Jio 4G"] } },
        { "$elemMatch": { "$eq": ["app_brand", "samsung"] } }
      ]   
    }
  }},
  { "$group": { "_id": "$userName" }
  { "$count": "unique_count"
])

所以在这个上下文中$elemMatch将检查每个“内部”数组并查看它是否与提供的条件匹配,我们将参数作为“数组”提供给$eq运算符。 / p>

换行$all表示必须满足所有提供的$elemMatch条件“才能满足查询条件。这就是用这种结构做出选择的方式。

如果你需要调整其中一个,那么“内部”匹配就是使用数组的元素。所以在密钥上它会使用"0"作为索引位置。即:

   { "$elemMatch": { "0": "app_os_version" } },