Есть ли способ вернуть определенные вложенные поля из запроса в MongoDB? - PullRequest
0 голосов
/ 13 февраля 2019

Есть ли способ получить сумму денег, выплаченную за категорию спорта ?Он не может быть ограничен только «Джоном», но во всех документах коллекции.

Ожидаемый запрос возврата для предоставленных данных:

{
  {"Fight":   [100,95] },
  {"Running": [50]     }
}

Примерданных:

{"_id":"5z621578b0ce483b9866fb1f",
 "Name":"John",
 "Sports":[
           {"Category":"Fight",
            "Billing":[
                       {"Month":"Jan",
                        "Status":"Paid",
                        "Price":100},
                      {"Month":"Feb",
                       "Status":"Not Paid",
                       "Price":125}, 
                      {"Month":"Mar",
                       "Status":"Paid",
                       "Price":95}      
                      ]
           },

          {"Category":"Running",
           "Billing":[
                      {"Month":"Jan",
                       "Status":"Not Paid",
                       "Price":200}, 
                      {"Month":"Feb",
                       "Status":"Paid",
                       "Price":50}  
                     ]
          }
      ]
}

Другими словами: мне нужно сравнить Статус биллинга внутри каждого вложенного объекта и проверить, является ли он "Платным" ,затем, если true, добавьте соответствующий объект выставления счетов Price к массиву соответствующей категории спорта .

Для всех документов в коллекции, с несколькими спортивными категориями и несколькими месяцами выставления счетов.Но всегда одна и та же вложенная структура.

Заранее спасибо!

1 Ответ

0 голосов
/ 16 февраля 2019

Как сказал Уиллис в своем комментарии, вы захотите использовать агрегацию: https://docs.mongodb.com/manual/aggregation/


Следующая агрегация даст вам данные, которые вы ищете (замените счета фактическим именемваша коллекция):

db.billings.aggregate([
    { $unwind: '$Sports'},
    { $unwind: '$Sports.Billing'},
    { $match: { 'Sports.Billing.Status': 'Paid' } },
    {
        $group: {
            _id: '$Sports.Category',
            Category: {$first: '$Sports.Category'},
            Prices: { $push: '$Sports.Billing.Price' }
        }
    },
    { $project: {_id: 0} }
]);

Результат этой агрегации будет выглядеть примерно так:

[
    {
        "Category" : "Running",
        "Prices" : [ 
            50.0
        ]
    },
    {
        "Category" : "Fight",
        "Prices" : [ 
            100.0, 
            95.0
        ]
    }
]

Точный формат, который вы запросили в своем вопросе, немного ненормальный;на мой взгляд, я думаю, что было бы лучше сохранить его в форме агрегации выше результатов.Но если вы хотите получить его в форме, подобной той, которая указана в вашем вопросе, агрегация будет немного более сложной:

db.billings.aggregate([
    { $unwind: '$Sports'},
    { $unwind: '$Sports.Billing'},
    { $match: { 'Sports.Billing.Status': 'Paid' } },
    {
        $group: {
            _id: '$Sports.Category',
            Prices: { $push: '$Sports.Billing.Price' }
        }
    },
    {
        $group: {
            _id: 0,
            Sports: { $push: { Category: '$_id', Prices: '$Prices' } }
        }
    },
    {
        $project: {
            Sports: {
                $arrayToObject: {
                    '$map': {
                        'input': '$Sports',
                        'as': 'el',
                        'in': {
                            'k': '$$el.Category',
                            'v': '$$el.Prices'
                        }
                    }
                }
            }
        }
    },
    { $replaceRoot: { newRoot: '$Sports'} }
]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...