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供您参考。

Mongo Playground

这与您想要的输出不同,但它只是 returns 与 provider_Id 匹配的数据。

    db.collection.aggregate({
  "$unwind": "$service"
},
{
  "$match": {
    "service.provider_id": "provider1"
  }
})

$unwind documentation $match documentation

我能够使用 $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