2015-06-25 59 views
2

我有一個MongoDB中的文檔集合,其中每個文檔都有一個包含數組的子文檔。MongoDB聚合與展開空陣列

{ 
    _id: <id> 
    key1: "value1", 
    key2: "value2", 
    ... 
    versions: [ 
    { version: 2, key1: <othervalue2>, key2: <othervalue2>} 
    { version: 1, key1: <othervalue2>, key2: <othervalue2>} 
    ] 
} 

我要查詢的集合,並與所有的字段返回文檔,用符合某些參數(或空數組時沒有匹配),數組的元素一起。使用我當前的代碼,只有在數組中至少有一個匹配的元素時才能得到結果。

我使用這些參數對於聚合:

{$match: {_id: <someID>}}, 
{$unwind: '$versions'}, 
{$match: {'versions.version': {$gte: <version>}}}, 
{$group: {_id: '$_id', key1: {$first: '$key1'}, ..., 'versions': {$push: '$versions'}} 

例如,查詢,其中arrayelement.version> = 2應返回(這可與當前代碼):

{ 
    _id: <id> 
    key1: "value1", 
    key2: "value2", 
    ... 
    versions: [ 
    { version: 2, key1: <othervalue2>, key2: <othervalue2>} 
    ] 
} 

而查詢arrayelement.version> = 4應該返回哪裏:

{ 
    _id: <id> 
    key1: "value1", 
    key2: "value2", 
    ... 
    versions: [] 
} 

我看過的解決方案都不是解決即使數組爲空也返回對象的問題。這甚至有可能嗎?

+0

您的'$匹配'聚合不符合標準。因此,它在空數組的情況下不返回任何結果 – gypsyCoder

+0

@gypsyCoder實際上'$ unwind'忽略空數組,因此這些文檔將永遠不會到達第二個'$ match'。 – zero323

回答

3

您可以檢查版本數組是否爲空,如果是這樣,請添加一些佔位符,例如空白文檔。省略管道的其餘部分也可能是這樣的:

[ 
    { 
     "$project" : { 
      "versions" : { 
       "$cond" : { 
        "if" : {"$eq" : [{"$size" : "$versions" }, 0]}, 
        "then" : [{ }], 
        "else" : "$versions" 
       } 
      }, 
      "_id" : 1 
     } 
    }, 
    { 
     "$unwind" : "$versions" 
    } 
] 

記住{$match: {'versions.version'}}在您的管道將篩選出來,所以你必須調整這一部分。

+0

謝謝!那樣做了。 下面的完整答案。 – John

0

感謝zero323讓我在正確的軌道上。全過濾器低於

{$match: {_id: <someid>}}, 
{ 
    "$project" : { 
     "versions" : { 
      "$cond" : { 
       "if" : {$or: [{$eq : [{$size : "$versions" }, 0]},{$eq : ["$version", <version>]}]}, 
       "then" : [null], 
       "else" : "$versions" 
      } 
     }, 
     "_id" : 1, 
     "key1": 1, 
     "key2": 1, 
     ... 
     "version": 1 

    } 
}, 
{$unwind: '$versions'}, 
{$match: {$or: [{'versions.version':{ $exists: false}},{'versions.version': {$gte: <version>}}]}}, 
{$group: {_id:'$_id',key1:{$first: '$key1'}, key2:{$first: '$key2'},...,version:{$first:'$version'},versions:{$push: '$versions'}}}, 
{ 
    "$project" : { 
     "versions" : { 
      "$cond" : { 
       "if" : {$eq : ["$versions", [null]]}, 
       "then" : [], 
       "else" : "$versions" 
      } 
     }, 
     "_id" : 1, 
     "key1": 1, 
     "key2": 1, 
     ... 
     "version": 1 
    } 
}