如何聚合两个集合,其中一个集合的字段大于另一个集合
How to aggregate two collections where a field from one collection is greater than the other
我有两个集合,我们称它们为集合 A 和集合 B,它们都有价格字段和商品编号。所以假设每个都有 2 个项目:
集合 A:
name = item1 , price = 30
name = item2 , price = 20
集合 B:
name = item1 , price = 50
name = item2 , price = 10
我想显示集合 A 的价格高于集合 B 的价格的项目。对于上面的示例,例如 item2。
如何编写这样的查询?我正在使用 robomongo。
(编辑)
跟进我之前的问题;
我想显示集合 A 的价格大于集合 B 的价格 *(汇率)+(某个常数)的项目
假设条件是;
where A's price > B's price*1.5+4
所以在这种情况下它应该仍然显示相同的项目。
假设条件是;
where A's price > B's price*1.5+10
那么它不应该显示任何项目
您可以使用 $lookup
operator to first do a join on collectionB
from collectionA
, flatten the single element array returned from the result with $unwind
and then use $redact
管道进行文档级修订,其中文档
符合指定条件的将使用 $$KEEP
system variable, and those that do not satisfy the condition are discarded using $$PRUNE
保留。最后,您需要 运行 以下聚合管道:
var exchangeRate = 1.5;
db.collectionA.aggregate([
{ "$match": { "price": { "$exists": true }, "name": { "$exists": true } } },
{
"$lookup": {
"from": "collectionB",
"localField": "name",
"foreignField": "name",
"as": "collectionB"
}
},
{ "$unwind": "$collectionB" },
{
"$redact": {
"$cond": [
{
"$gt": [
"$price", {
"$add": [
{ "$multiply": [ "$collectionB.price", exchangeRate ] },
4
]
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Robomongo 演示
填充测试集合:
db.collectionA.insert([
{ "name": "item1", "price": 30 },
{ "name": "item2", "price": 20 }
])
db.collectionB.insert([
{ "name": "item1", "price": 50 },
{ "name": "item2", "price": 10 }
])
运行 并调试聚合管道:
示例输出:
{
"_id" : ObjectId("58ad50a429b2961777f91c95"),
"name" : "item2",
"price" : 20,
"collectionB" : {
"_id" : ObjectId("58ad50a429b2961777f91c97"),
"name" : "item2",
"price" : 10
}
}
我有两个集合,我们称它们为集合 A 和集合 B,它们都有价格字段和商品编号。所以假设每个都有 2 个项目:
集合 A:
name = item1 , price = 30
name = item2 , price = 20
集合 B:
name = item1 , price = 50
name = item2 , price = 10
我想显示集合 A 的价格高于集合 B 的价格的项目。对于上面的示例,例如 item2。
如何编写这样的查询?我正在使用 robomongo。
(编辑)
跟进我之前的问题;
我想显示集合 A 的价格大于集合 B 的价格 *(汇率)+(某个常数)的项目
假设条件是;
where A's price > B's price*1.5+4
所以在这种情况下它应该仍然显示相同的项目。
假设条件是;
where A's price > B's price*1.5+10
那么它不应该显示任何项目
您可以使用 $lookup
operator to first do a join on collectionB
from collectionA
, flatten the single element array returned from the result with $unwind
and then use $redact
管道进行文档级修订,其中文档
符合指定条件的将使用 $$KEEP
system variable, and those that do not satisfy the condition are discarded using $$PRUNE
保留。最后,您需要 运行 以下聚合管道:
var exchangeRate = 1.5;
db.collectionA.aggregate([
{ "$match": { "price": { "$exists": true }, "name": { "$exists": true } } },
{
"$lookup": {
"from": "collectionB",
"localField": "name",
"foreignField": "name",
"as": "collectionB"
}
},
{ "$unwind": "$collectionB" },
{
"$redact": {
"$cond": [
{
"$gt": [
"$price", {
"$add": [
{ "$multiply": [ "$collectionB.price", exchangeRate ] },
4
]
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Robomongo 演示
填充测试集合:
db.collectionA.insert([
{ "name": "item1", "price": 30 },
{ "name": "item2", "price": 20 }
])
db.collectionB.insert([
{ "name": "item1", "price": 50 },
{ "name": "item2", "price": 10 }
])
运行 并调试聚合管道:
示例输出:
{
"_id" : ObjectId("58ad50a429b2961777f91c95"),
"name" : "item2",
"price" : 20,
"collectionB" : {
"_id" : ObjectId("58ad50a429b2961777f91c97"),
"name" : "item2",
"price" : 10
}
}