2015-04-22 2 views
3

Как часть конвейера агрегации, я хотел бы проецировать новое поле на документ, который представляет собой минимум два существующих поля.

Указанные документы, подобные этим:

{ 
    _id: "big1", 
    size: "big", 
    distances: { big: 0, medium: 0.5, small: 1 } 
} 
{ 
    _id: "med1", 
    size: "medium", 
    distances: { big: 0.5, medium: 0, small: 0.5 } 
} 
{ 
    _id: "small1", 
    size: "small", 
    distances: { big: 1, medium: 0.5, small: 0 } 
} 

«расстояния» поддокумент показывает, как «далеко» размер документа от других возможных размеров.

Я ищу для накопления сортировки для документов, которые показывают, насколько близко к набору параметров. Если бы я искал только «большие» документы, я мог бы сделать это:

aggregate([ 
    {$project: {"score": "$distances.big"}} 
    {$sort: {"score": 1}} 
]); 

Но предположим, что я хочу, чтобы разобраться в равной степени для «больших» или документов «средних». То, что я хочу что-то вроде:

aggregate([ 
    {$project: {"score": {$min: ["$distances.big", "$distances.medium"]}}}, 
    {$sort: {"score": 1}} 
]) 

Но это не работает, так как $ мин работает только на смежных документов в $ группового запроса.

Есть ли способ проецировать значение, которое является минимальным из двух существующих полей в качестве параметра сортировки?

ответ

3

Вы можете использовать оператор $cond выполнить сравнение, которое находит минимальное значение с помощью оператора: $lt

db.test.aggregate([ 
    {$project: {score: {$cond: [ 
     {$lt: ['$distances.big', '$distances.medium']}, // boolean expression 
     '$distances.big', // true case 
     '$distances.medium' // false case 
    ]}}}, 
    {$sort: {score: 1}} 
]) 

Результат:

[ 
    { 
     "_id" : "big1", 
     "score" : 0 
    }, 
    { 
     "_id" : "med1", 
     "score" : 0 
    }, 
    { 
     "_id" : "small1", 
     "score" : 0.5 
    } 
] 
Смежные вопросы