我有3个有许多记录的集合。每个都有一些键,如价格,名称,…
如您所见,c
collection中的price字段与data.detail
collection中的price字段不同。
我想根据name
计算这些收藏品的平均价格。
最终结果应该是带有计算价格的产品数组。这可能吗?
collection a = [
{"id":1, "price": "1200", "name": "x1"},
{"id":2, "price": "2000", "name": "x2"},
{"id":3, "price": "3000", "name": "x3"},
...
]
collection b = [
{"id":1, "price": "1500", "name": "x1"},
{"id":2, "price": "2500", "name": "x2"},
{"id":3, "price": "3125", "name": "x3"},
...
]
collection c = [
{"id":1, "data": {"detail": {"price": 1900}}, "name": "x1"},
{"id":2, "data": {"detail": {"price": 2900}}, "name": "x2"},
{"id":3, "data": {"detail": {"price": 3500}}, "name": "x3"},
...
]
我想要这个作为结果:
$result = [
{"id":1, "price": "1533.3", "name": "x1"},
{"id":2, "price": "2466.6", "name": "x2"},
{"id":2, "price": "3208.3", "name": "x3"},
...
]
你可以试试这个查询:
- 第一个
$lookup
两次与集合B
和C
进行JOIN。 - 然后
$unwind
解构$lookup
生成的数组。 - 这里我已经解析到int值,因为在你的数据示例是字符串,我不知道它是一个错字或数据是字符串。如果您的数据已经是整数,则可以避免此阶段。
- 然后重新组合值,为每个价格(A, B和C)生成一个数组。
- 并计算平均值。
db.a.aggregate([
{
"$lookup": {
"from": "b",
"localField": "name",
"foreignField": "name",
"as": "b"
}
},
{
"$lookup": {
"from": "c",
"localField": "name",
"foreignField": "name",
"as": "c"
}
},
{
"$unwind": "$b"
},
{
"$unwind": "$c"
},
{
"$set": {
"b.price": {
"$toInt": "$b.price"
},
"price": {
"$toInt": "$price"
}
}
},
{
"$group": {
"_id": "$_id",
"name": {
"$first": "$name"
},
"id": {
"$first": "$id"
},
"priceA": {
"$push": "$price"
},
"priceB": {
"$push": "$b.price"
},
"priceC": {
"$push": "$c.data.detail.price"
}
}
},
{
"$set": {
"price": {
"$concatArrays": [
"$priceA",
"$priceB",
"$priceC"
]
}
}
},
{
"$project": {
"_id": 0,
"id": 1,
"name": 1,
"price": {
"$avg": "$price"
}
}
}
])
例子
对于您的输入示例,它可以工作,检查它是否仍然适用于其他输入数据。