2015-12-02 2 views
1

Я пытаюсь собрать совокупность рецептов. Каждый рецепт в коллекции имеет поле calories, которое представляет собой количество калорий в одной порции. Мне нужно найти рецепты с калориями, ближайшими к за 1, 2 и 3 порции. Я знаю, что вы не можете использовать оператор $ min так, как я сделал ниже, но он просто должен дать идею.Структура агрегации Mongo: поиск минимального значения в пределах прогнозируемых значений

[ 
    { 
     $project: { 
     recipe: "$$ROOT", 
     "caloriesInOneServing": "$calories", 
     "caloriesInTwoServings": {$multiply: ["$calories", 2.0]}, 
     "caloriesInThereServings": {$multiply: ["$calories", 3.0]} 
     } 
    }, 
    { 
     $project: { 
     recipe: 1, 
     "caloriesInOneServingDiff": {$subtract: ["$caloriesInOneServing", 1000], 
     "caloriesInTwoServingsDiff": {$subtract: ["$caloriesInTwoServings", 1000], 
     "caloriesInThereServingsDiff": {$subtract: ["$caloriesInThereServings", 1000] 
     } 
    }, 
    { 
     $project: { 
     recipe: 1, 
     //how do i find the min value among given fields? 
     minDiff: {$min: [$caloriesInOneServingDiff, caloriesInTwoServingsDiff, caloriesInThereServingsDiff] 
     } 
    }, 
    { 
     $sort: { minDiff: -1 } 
    } 
    ] 
+0

Вам будет лучше, если вы сможете показать образец документа с ожидаемым результатом. – styvane

ответ

0

Это может быть сделано с помощью условного вычитания:

[ 
    { 
     $project: { 
     recipe: "$$ROOT", 
     "caloriesInOneServing": "$calories", 
     "caloriesInTwoServings": {$multiply: ["$calories", 2.0]}, 
     "caloriesInThereServings": {$multiply: ["$calories", 3.0]} 
     } 
    }, 
    { 
     $project: { 
     recipe: 1, 
     "caloriesInOneServingDiff": {$cond: [ 
       { $lt: ['$caloriesInOneServing', 1000] }, 
       { $subtract: [1000, '$caloriesInOneServing'] }, 
       { $subtract: ['$caloriesInOneServing', 1000] } 
      ]}, 
     "caloriesInTwoServingsDiff": {$cond: [ 
       { $lt: ['$caloriesInTwoServings', 1000] }, 
       { $subtract: [1000, '$caloriesInTwoServings'] }, 
       { $subtract: ['$caloriesInTwoServings', 1000] } 
      ]}, 
     "caloriesInThereServingsDiff": {$cond: [ 
       { $lt: ['$caloriesInThereServings', 1000] }, 
       { $subtract: [1000, '$caloriesInThereServings'] }, 
       { $subtract: ['$caloriesInThereServings', 1000] } 
      ]} 
     } 
    }, 
    { 
     $project: { 
     recipe: 1, 
     minDiff: {$min: [$caloriesInOneServingDiff, caloriesInTwoServingsDiff, caloriesInThereServingsDiff] 
     } 
    }, 
    { 
     $sort: { minDiff: -1 } 
    } 
    ] 

Пример:

calories = 300 
x2 = 600 
x3 = 900 

после условного вычитания:

caloriesDiff = 700 
x2Diff = 400 
x3Diff = 100 

мин = x3, которая находится ближе всего к 1000

+0

Огромное значение $ cond, но как насчет $ min, afaik, вы можете использовать его только с агрегацией h $ group и NOT с $ project. Не так ли? – Dziamid

+0

@Dziamid Ах, правильно, забыли об этом. Должен работать, но я думаю, что, поскольку Mongo работает на движке V8 JS, он должен иметь доступ к объекту 'Math', который имеет функцию' min() '. Поскольку '$ project' принимает выражение, вы должны использовать это _I think_. Если нет, я выложу решение, когда вернусь. –

+0

Math.min не будет работать, потому что мы не передаем какие-либо функции агрегированному методу, структура агрегации не позволяет этого. – Dziamid

Смежные вопросы