2017-02-18 100 views
2

我在mongodb聚合中有匹配表達式。比賽中包含3個字段,但並不總是包含數據。如果該字段不爲空,我只想在匹配中包含這些字段。如何動態構建mongodb查詢

這就是匹配的樣子,如果所有的字段都有數據,但是例如,如果用於studentGradeLevels的數組爲空,那麼我不想包含它,或者我希望查詢仍然返回數據而忽略空的參數。

$match: { 
    "school._id": "7011", 
    "studentGradeLevels": { $in: ["09", "10", "11", "12"] }, 
    "contentArea": { 
     $in: [ 
      "English 1" 
     ] 
    } 
} 

有沒有辦法要麼動態地構建了比賽,這樣我只包括基於它們是否爲空或不或做一些查詢,以便是空的參數被忽略我想要的字段。

回答

2

您可以使用$in當數組不爲空,並$nin當數組是空的,這樣的比賽場將不被考慮在內($nin : []):

function buildMatch(arr) { 
    var matcher = {}; 
    if (arr.length == 0) 
     matcher["$nin"] = arr; 
    else 
     matcher["$in"] = arr; 
    return matcher; 
} 

var grades = ["09", "10", "11", "12"]; 
var areas = [ "English 2" ]; 

var gradeMatch = buildMatch(grades); 
var areaMatch = buildMatch(areas); 

db.students.aggregate([{ 
    $match: { 
     "school._id": "7011", 
     "studentGradeLevels": gradeMatch, 
     "contentArea": areaMatch 
    } 
}]) 
+0

看起來像這樣回答「如果我的查詢參數爲空,該怎麼辦」。我認爲OP想要這樣做:「如果我查詢contentArea和schoolGradeLevels,並且候選文檔都設置了這兩個字段,則嘗試匹配,但是如果例如schoolGradeLevels沒有設置在候選人中,那麼甚至不要嘗試匹配該字段;只是嘗試匹配contentArea。「 –

0

的變化:檢查字段是否存在,如果是的話,改爲一個特殊的價值,例如_並將其添加到$in列表中:

db.foo.aggregate([ 
{$project: {"studentGradeLevels":{$ifNull: ["$studentGradeLevels","_"]}, 
      "contentArea":{$ifNull: ["$contentArea","_"]} 
}} 
,{$match: { 
     "studentGradeLevels": { $in: ["_", "09", "10", "11", "12"] }, 
     "contentArea": { $in: [ "_", "English 1" ] } 
}} 
       ]);