从3个不同的集合中得到某个键的平均值



我有3个有许多记录的集合。每个都有一些键,如价格,名称,…

如您所见,ccollection中的price字段与data.detailcollection中的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两次与集合BC进行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"
}
}
}
])

例子

对于您的输入示例,它可以工作,检查它是否仍然适用于其他输入数据。

最新更新