2017-02-18 3 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, а у кандидата doc оба поля установлены, то попытайтесь сопоставить. Но если, например, 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" ] } 
}} 
       ]); 
Смежные вопросы