Mongodb多对多获取相关项目

时间:2019-07-07 15:23:28

标签: mongodb mongodb-query aggregation-framework

我有3个与多对多关系的mongodb集合, 产品功能集合是关系集合。

//Sleep for five seconds.
sleep(5);

//Redirect using the Location header.
header('Location: case_management.php?id=<? echo $rows['case_id']; ?>');
//Post reply drawn
$sla_client = $_POST['sla_client'];
$case_id = $_POST['case_id'];
$status = $_POST['status'];

我想获得产品的所有功能,如下所示?

db={
  "products": [
    {
      "id": 1,
      "name": "product 1"
    }
  ],
  "features": [
    {
      "id": 101,
      "name": "width"
    },
    {
      "id": 102,
      "name": "length"
    },
    {
      "id": 103,
      "name": "height"
    }
  ],
  "productfeatures": [
    {
      "productId": 1,
      "featureId": 101,
      "value": "3"
    },
    {
      "productId": 1,
      "featureId": 102,
      "value": "4"
    },
    {
      "productId": 1,
      "featureId": 103,
      "value": "5"
    }
  ]
}

我知道如何在查找阶段获得产品功能:

[
  {
    "id": 1,
    "name": "product 1",
    "productfeatures": [
        {
        "feature": "width",
        "value": "3"
      },
      {
        "feature": "length",
        "value": "4"
      },
      {
        "feature": "height",
        "value": "5"
      }
    ]
  }
]

但是我也想加入功能集合以获取功能名称。

https://mongoplayground.net/p/J-20zxxFW5q

2 个答案:

答案 0 :(得分:1)

您可以在多个mongodb aggregation pipeline阶段使用$lookup来实现这一目标。

您走的路正确,您需要添加一个$unwind阶段(以展开第一个lookup阶段的结果)和$lookup阶段,最后将所有结果,您将需要最后一个$group阶段,才能将所有功能组合到一个数组中。

尝试一下:

db.products.aggregate([
    {
        $match: {
            id: 1
        }
    },
    {
        $lookup: {
            from: "productfeatures",
            localField: "id",
            foreignField: "productId",
            as: "productfeatures"
        }
    },{
        $unwind : "$productfeatures"
    },{
        $lookup : {
            from : "features",
            local : "productfeatures.featureId",
            foreignField : "id",
            as : "feature"
        }
    },{
        $unwind : "$feature"
    },{
        $group : {
            _id : "$_id",
            name : {$first : "$name"},
            productfeatures : {$push : "$feature"}

        }
    }
])

请阅读有关$group$unwind$lookup的更多信息。

答案 1 :(得分:1)

您可以使用以下汇总

db.products.aggregate([
  { "$match": { "id": 1 }},
  { "$lookup": {
    "from": "productfeatures",
    "let": { "productId": "$id" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$$productId", "$productId"] }}},
      { "$lookup": {
        "from": "features",
        "let": { "featureId": "$featureId" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": ["$id", "$$featureId"] }}}
        ],
        "as": "productfeatures"
      }},
      { "$project": {
        "value": 1,
        "feature": { "$arrayElemAt": ["$productfeatures.name", 0] }
      }}
    ],
    "as": "productfeatures"
  }}
])

MongoPlayground