2016-08-13 313 views
2

我有一個文檔集合,我希望按字段進行分組,除非它不存在,那麼我想按第二個字段進行分組。

例如,考慮這4個文件:

{ 
    prop1: 'anything', 
    prop2: 1 
}, 
{ 
    prop1: 'anything', 
    prop2: 2 
}, 
{ 
    prop1: 'something' 
}, 
{ 
    prop1: 'something else' 
} 

當我按 'PROP2' 我會得到3個分組結果。一爲:

PROP2 == 1和

PROP2 == 2和

PROP2 ==未定義

但我希望得到4個結果。一爲:

PROP2 == 1和

PROP2 == 2和

PROP1 == '東西' 和

PROP1 == '別的東西'

這甚至可能嗎?這是一個非常複雜的查詢嗎?我最好填補缺失的領域,以便它可以分組?

回答

2

您需要在$group階段使用$ifNull條件聚合操作符。

db.coll.aggregate([ 
    { "$group": { "_id": { "$ifNull": [ "$prop1", "$prop2" ] } } } 
]) 

$ifNull的操作者返回第二個表達式的值,如果第一表達式的計算結果爲空值,或者如果該字段是丟失。這就是你想要的。


您可能需要一個$project階段添加到您的管道,但是這是將是多餘的,造成的性能在應用程序的下降。

+0

這正是我所期待的。謝謝。 – smdufb

2

可以在$project階段使用$ifNull運營商分組之前如下

db.cullection.aggregate(
    { $project: { "groupVal": { $ifNull: [ '$prop2', '$prop1' ] } } }, 
    { $group: { "_id": "$groupVal" } } 
); 

對於每一個文檔,將根據其應在下一階段$group進行分組設定的值groupVal。因此,對於定義了prop2字段的文檔,將從prop2中選擇值,否則將從prop1中獲取值。

+0

這可能是由於我對mongodb及其查詢缺乏瞭解。但是在$ project階段執行此操作會以某種方式在結果中將累積器設置爲小組階段(例如'prop1:{$ first:'$ prop1'}')爲'null'。 – smdufb

+0

是的,只有一個「$ group」階段的解決方案肯定更好!我沒有注意到'$ ifNull'操作符可以用在'$ group'階段以及'$ project'階段。您可以在'$ project'階段使用[**'$$ ROOT' **](https://docs.mongodb.com/manual/reference/aggregation-variables/#variable.ROOT)運算符來傳遞整個文檔沒有'null'值到'$ group'階段。 – tarashypka