#database #mongodb
Вопрос:
У меня есть две коллекции, компьютеры, которые показаны ниже
{"_id":{"$oid":"6185bee4aca3214e77e748a9"},"name":"Gaming PC","manufacturer":"Dell","category":["Gaming"],"colour":"black","price":1200.0,"quantity":47.0,"weight":10.0,"parts":[{"type":"motherboard","manufacturer":"AMD","cost":150.0,"description":"Motherboard suitable for gaming PCs"},{"type":"ram","manufacturer":"Corsair","cost":50.0,"description":"16gb 2400mhz RAM"},{"type":"cpu","manufacturer":"Intel","cost":250.0,"description":"AMD 5600X Processor"},{"type":"gpu","manufacturer":"NVIDIA","cost":600.0,"description":"NVIDIA GTX3080"},{"type":"storage","manufacturer":"Seagate","cost":80.0,"description":"1TB SSD"}],"reviews":["review01","review02","review10"]},
{"_id":{"$oid":"6185c06eaca3214e77e748aa"},"name":"Office PC","manufacturer":"HP","category":["Work","Office"],"colour":"black","price":400.0,"quantity":102.0,"weight":12.0,"parts":[{"type":"motherboard","manufacturer":"XYZ","cost":70.0,"description":"Reliable motherboard"},{"type":"ram","manufacturer":"HP","cost":10.0,"description":"4gb 2400mhz RAM"},{"type":"cpu","manufacturer":"Intel","cost":100.0,"description":"Built In Processor"},{"type":"gpu","manufacturer":"HP","cost":75.0,"description":"On board graphics"},{"type":"storage","manufacturer":"Seagate","cost":20.0,"description":"1TB HDD"}],"reviews":["review03"]},
{"_id":{"$oid":"6185c244aca3214e77e748ab"},"name":"Chromebook","manufacturer":"Acer","category":["Portable","Lightweight","Work","Student"],"colour":"red","price":350.0,"quantity":61.0,"weight":4.0,"parts":[{"type":"motherboard","manufacturer":"XYZ","cost":40.0,"description":"Reliable motherboard for Laptops"},{"type":"ram","manufacturer":"Acer","cost":10.0,"description":"Built in 4gb RAM"},{"type":"cpu","manufacturer":"AMD","cost":100.0,"description":"Built In Processor"},{"type":"gpu","manufacturer":"Acer","cost":45.0,"description":"On board graphics"},{"type":"storage","manufacturer":"Acer","cost":25.0,"description":"64GB HDD"}],"reviews":["review04","review05"]}
И коллекция отзывов;
{"_id":"review01","reviewer":"Jack Weir","rating":5.0,"text":"Very good product!","created":"2021, 08, 03"},
{"_id":"review02","reviewer":"Adam Smith","rating":3.0,"text":"Good value for money","created":"2021, 09, 04"},
{"_id":"review03","reviewer":"Luke Bridges","rating":1.0,"text":"Not good!","created":"2021, 10, 21"},
{"_id":"review04","reviewer":"Richard Lamb","rating":4.0,"text":"Runs very smoothly","created":"2021, 11, 03"},
{"_id":"review05","reviewer":"Pamela Halpert","rating":4.0,"text":"Easy to setup","created":"2021, 11, 04"},
{"_id":"review06","reviewer":"Michael Scott","rating":5.0,"text":"Would highly recommend","created":"2021, 11, 05"},
{"_id":"review07","reviewer":"Angela Lewis","rating":2.0,"text":"A bit too pricey","created":"2021, 11, 06"},
{"_id":"review08","reviewer":"Dexter Morgan","rating":3.0,"text":"Does the job","created":"2021, 11, 06"},
{"_id":"review09","reviewer":"Lisa Simpson","rating":2.0,"text":"Okay but not great","created":"2021, 11, 06"},
{"_id":"review10","reviewer":"Marge Simpson","rating":5.0,"text":"Wonderful Computer exactly what I was after!","created":"2021, 11, 07"}
Как мне написать запрос, который может возвращать название каждого продукта и среднюю оценку, которую он получил от любых оценок в свойстве «Обзор»?
Например, я хотел бы, чтобы результат запроса отображал «имя:» Игровой ПК», Средний рейтинг: 4,3″
Ответ №1:
Вам нужно только $lookup
присоединиться к коллекциям (получить данные рецензентов в коллекцию компьютеров) и сделать $avg
это, чтобы получить среднее значение.
db.computers.aggregate({
"$lookup": {
"from": "reviews",
"localField": "reviews",
"foreignField": "_id",
"as": "reviewers"
}
},
{
"$project": {
"name": 1,
"avg": {
"$avg": "$reviewers.rating"
}
}
})
Пример здесь
Этот запрос выводит только данные name
и avg
поля, но вы можете добавить в $project
этап столько полей, сколько захотите. Также вы можете использовать $set
или $addFields
вместо проекта, чтобы не потерять все значения (пример)