匹配的文件上嵌套数组值和计数独特

匹配的文件上嵌套数组值和计数独特

问题描述:

我有一个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结束日期,名为x(例如APPSESSION),包含多个属性嵌套阵列(例如[ “app_installAt”, “这可以是任何值,而不是空 ”],[“ app_model”, “这可以是任何值空“]的TEAD,等...),集团通过的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个索引。

请帮忙。

由于提前.... :)

+0

我可以指出,数据看起来像这样的唯一方法是因为代码错误更新到它的第一位。修正代码写错的代码会不会更合乎逻辑?这完全是存储这个错误的方法。 –

+0

是的,我知道,但编写数据的算法是相同的,数据非常巨大,以至于改变数据结构也是不可行的,因为它包含TB的数据。 – Shashank

+2

如果是Terrabytes的数据,那么更有理由修复它。现在,您无法有效地使用索引来帮助查询结果。在所有标准实际上都基于具有特定路径的键和值的数组的情况下,那么索引将更加有效且速度更快。无论如何,我已经用当前格式的查询回答了这个问题。 –

查询为这个基本上是利用$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在这种情况下将要检查每个“内”阵列,看看它是否所提供的条件,这是我们得到在参数作为一个“阵列”的匹配运营商。

包装$all意味着所有提供的$elemMatch条件必须满足以满足查询条件。这就是选择这种结构的方式。

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

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

那么我知道数组中的“app_os_version”,而不是“6.0.1”,我想从数组的属性数组中过滤所有结果,其中我知道只有数组第一个元素和不是第二个 – Shashank

+0

@Shashank使用'$ elemMatch'内的“索引”位置。添加回答来演示。 –