Mongodb 查询:仅当满足特定条件时才加入文档
Mongodb query: getting join of docs only if satisfies a specific condition
我希望 mongodb 查询给出以下这些详细信息,并获得最佳性能。
让我先举个例子:
给我一个collection,
/// the collection
services =
[
{
_id: obj(id1),
provider_id: "provider1",
service_code: "code1",
price: 20
},
{
_id: obj(id2),
provider_id: "provider1",
service_code: "code2",
price: 20
},
{
_id: obj(id3),
provider_id: "provider1",
service_code: "code3",
price: 20
},
{
_id: obj(id4),
provider_id: "provider2",
service_code: "code1",
price: 10
},
{
_id: obj(id5),
provider_id: "provider2",
service_code: "code2",
price: 20
},
{
_id: obj(id6),
provider_id: "provider3",
service_code: "code1",
price: 20
}
]
我想获取所有(仅)支持这两个服务代码的服务提供商:代码 1、代码 2。
并且总价按总价排序。
输出是这样的:
/// required output based the posted collection and required requirements.
output =
[
{
provider_id: "provider1",
total_price: 40,
},
{
provider_id: "provider2",
total_price: 30,
}
]
我不想要这个输出:
[
{
"_id": "provider1",
"total_price": 40
},
{
"_id": "provider2",
"total_price": 30
},
{
"_id": "provider3",
"total_price": 20
}
]
如何做到这一点?谢谢
这可能是 $group
最基本的用例。
db.collection.aggregate([
{
$match: {
service_code: {
$in: [
"code1",
"code2"
]
}
}
},
{
"$group": {
"_id": "$provider_id",
"service_codes": {
"$addToSet": "$service_code"
},
"total_price": {
"$sum": "$price"
}
}
},
{
$match: {
$expr: {
$eq: [
{
"$setIntersection": [
"$service_codes",
[
"code1",
"code2"
]
]
},
[
"code1",
"code2"
]
]
}
}
},
{
$project: {
service_codes: false
}
},
{
$sort: {
total_price: -1
}
}
])
这里是Mongo playground供您参考。
这与您想要的输出不同,但它只是 returns 与 provider_Id 匹配的数据。
db.collection.aggregate({
"$unwind": "$service"
},
{
"$match": {
"service.provider_id": "provider1"
}
})
我能够使用 $project:
获得你需要的输出
db.collection.aggregate([
{
$match: {
service_code: {
$in: [
"code1",
"code2"
]
}
}
},
{
"$group": {
"_id": "$provider_id",
"total_price": {
"$sum": "$price"
}
}
},
{
"$project": {
"provider_id": "$_id",
"total_price": 1,
"_id": 0
},
},
{
$sort: {
total_price: -1
}
}
])
我稍微修改了射线答案并添加了项目聚合:) 我的游乐场在这里Mongo Playground
我希望 mongodb 查询给出以下这些详细信息,并获得最佳性能。
让我先举个例子:
给我一个collection,
/// the collection
services =
[
{
_id: obj(id1),
provider_id: "provider1",
service_code: "code1",
price: 20
},
{
_id: obj(id2),
provider_id: "provider1",
service_code: "code2",
price: 20
},
{
_id: obj(id3),
provider_id: "provider1",
service_code: "code3",
price: 20
},
{
_id: obj(id4),
provider_id: "provider2",
service_code: "code1",
price: 10
},
{
_id: obj(id5),
provider_id: "provider2",
service_code: "code2",
price: 20
},
{
_id: obj(id6),
provider_id: "provider3",
service_code: "code1",
price: 20
}
]
我想获取所有(仅)支持这两个服务代码的服务提供商:代码 1、代码 2。
并且总价按总价排序。
输出是这样的:
/// required output based the posted collection and required requirements.
output =
[
{
provider_id: "provider1",
total_price: 40,
},
{
provider_id: "provider2",
total_price: 30,
}
]
我不想要这个输出:
[
{
"_id": "provider1",
"total_price": 40
},
{
"_id": "provider2",
"total_price": 30
},
{
"_id": "provider3",
"total_price": 20
}
]
如何做到这一点?谢谢
这可能是 $group
最基本的用例。
db.collection.aggregate([
{
$match: {
service_code: {
$in: [
"code1",
"code2"
]
}
}
},
{
"$group": {
"_id": "$provider_id",
"service_codes": {
"$addToSet": "$service_code"
},
"total_price": {
"$sum": "$price"
}
}
},
{
$match: {
$expr: {
$eq: [
{
"$setIntersection": [
"$service_codes",
[
"code1",
"code2"
]
]
},
[
"code1",
"code2"
]
]
}
}
},
{
$project: {
service_codes: false
}
},
{
$sort: {
total_price: -1
}
}
])
这里是Mongo playground供您参考。
这与您想要的输出不同,但它只是 returns 与 provider_Id 匹配的数据。
db.collection.aggregate({
"$unwind": "$service"
},
{
"$match": {
"service.provider_id": "provider1"
}
})
我能够使用 $project:
获得你需要的输出db.collection.aggregate([
{
$match: {
service_code: {
$in: [
"code1",
"code2"
]
}
}
},
{
"$group": {
"_id": "$provider_id",
"total_price": {
"$sum": "$price"
}
}
},
{
"$project": {
"provider_id": "$_id",
"total_price": 1,
"_id": 0
},
},
{
$sort: {
total_price: -1
}
}
])
我稍微修改了射线答案并添加了项目聚合:) 我的游乐场在这里Mongo Playground