从 3 个不同的 collection 中获取某个键的平均值
get everage value of certain key form 3 diffrent collection
我有 3 个 collection 有很多记录。
他们每个人都有一些关键,比如价格、名字、...
如您所见,在 collection c
上提交的价格与其他 collection 不同,价格在 data.detail
字段中。
我想根据 name
.
计算那里 collection 的平均价格
最终结果应该是计算价格的产品数组。可能吗?
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"
}
}
}
])
示例here
对于你的输入示例它有效,检查它是否仍然适用于其他输入数据。
我有 3 个 collection 有很多记录。 他们每个人都有一些关键,比如价格、名字、...
如您所见,在 collection c
上提交的价格与其他 collection 不同,价格在 data.detail
字段中。
我想根据 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"
}
}
}
])
示例here
对于你的输入示例它有效,检查它是否仍然适用于其他输入数据。