2017-07-08 82 views
0

我有一個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的數據,那麼更有理由修復它。現在,您無法有效地使用索引來幫助查詢結果。在所有標準實際上都基於具有特定路徑的鍵和值的數組的情況下,那麼索引將更加有效且速度更快。無論如何,我已經用當前格式的查詢回答了這個問題。 –

回答

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在這種情況下將要檢查每個「內」陣列,看看它是否所提供的條件,這是我們得到在參數作爲一個「陣列」的匹配運營商。

包裝$all意味着所有提供的$elemMatch條件必須滿足以滿足查詢條件。這就是選擇這種結構的方式。

如果您需要調整其中一個,則「內部」匹配使用數組的元素。所以在密鑰上它將使用"0"作爲索引位置。即:

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

那麼我知道數組中的「app_os_version」,而不是「6.0.1」,我想從數組的屬性數組中過濾所有結果,其中我知道只有數組第一個元素和不是第二個 – Shashank

+0

@Shashank使用'$ elemMatch'內的「索引」位置。添加回答來演示。 –