You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用复合主键匹配产品与描述并生成两类报表

MongoDB复合主键集合关联匹配与报表生成方案

问题分析

核心问题是**$lookup关联后,最后$project阶段字段引用错误**:products集合的productId和categoryId是嵌套在_id复合主键下的子字段,而非根级别字段,原代码直接写"productId": 1无法正确提取值,导致查询结果不符合预期。以下基于关联逻辑给出两类报表的完整解决方案。

集合结构回顾

// products集合(复合主键)
{
  "_id" : {
    "productId" : NumberLong(23300),
    "categoryId" : NumberLong(7777)
  },
  "name" : "Musk Spray",
  "quantity" : 12333,
  "category" : "Fragrance",
  "price" : 122.99,
  "descriptionCode" : NumberLong(75),
  "brand" : "Musk Cologne",
  "updatedDate" : ISODate("2023-01-03T20:46:45.099+0000"),
  "createdDate" : ISODate("2023-01-03T20:46:45.099+0000")
}

// product-info集合
{
  "_id" : ObjectId("572179b333316ab012"),
  "productId": NumberLong(23300),
  "categoryId": NumberLong(7777),
  "descriptionCode" : NumberLong(75),
  "price" : 122.99,
  "description" : "Medium Range Cologne For Men"
}

解决方案

1. 无描述产品报表查询(修正版)

修正字段引用逻辑,同时优化空数组判断方式:

db.products.aggregate([
  {
    "$lookup": {
      "from": "product-info",
      "let": {
        "productId": "$_id.productId",
        "categoryId": "$_id.categoryId"
      },
      "as": "productInfo",
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$and": [
                {"$eq": ["$productId", "$$productId"]},
                {"$eq": ["$categoryId", "$$categoryId"]}
              ]
            }
          }
        },
        {
          "$project": {
            "_id": 0,
            "description": 1
          }
        }
      ]
    }
  },
  {
    // 筛选无匹配描述的产品
    "$match": {
      "productInfo": []
    }
  },
  {
    "$project": {
      "_id": 0,
      "productId": "$_id.productId", // 从复合主键正确提取字段
      "categoryId": "$_id.categoryId",
      "name": 1,
      "quantity": 1 // 按需添加其他需要展示的字段
    }
  }
])

2. 带描述产品报表查询

基于同一关联逻辑,筛选有匹配描述的产品并合并描述字段:

db.products.aggregate([
  {
    "$lookup": {
      "from": "product-info",
      "let": {
        "productId": "$_id.productId",
        "categoryId": "$_id.categoryId"
      },
      "as": "productInfo",
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$and": [
                {"$eq": ["$productId", "$$productId"]},
                {"$eq": ["$categoryId", "$$categoryId"]}
              ]
            }
          }
        },
        {
          "$project": {
            "_id": 0,
            "description": 1
          }
        }
      ]
    }
  },
  {
    // 筛选有匹配描述的产品
    "$match": {
      "productInfo": {"$ne": []}
    }
  },
  {
    // 将数组中的描述提取为根级别字段,简化结果结构
    "$addFields": {
      "description": {"$arrayElemAt": ["$productInfo.description", 0]}
    }
  },
  {
    "$project": {
      "_id": 0,
      "productId": "$_id.productId",
      "categoryId": "$_id.categoryId",
      "name": 1,
      "quantity": 1,
      "price": 1,
      "description": 1
    }
  }
])

关键优化说明

  • 字段引用修正:复合主键下的字段必须通过$_id.xxx格式提取,不能直接使用根级别字段名。
  • 空数组判断简化:直接用"productInfo": []判断关联结果为空,比$size表达式更高效。
  • 结果结构优化:带描述报表中用$arrayElemAt将数组内的描述转为单值字段,避免结果嵌套冗余数组。

内容的提问来源于stack exchange,提问作者BreenDeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:10:34