代码之家  ›  专栏  ›  技术社区  ›  Kyle Richardson

嵌套localfield时的$lookup

  •  1
  • Kyle Richardson  · 技术社区  · 8 年前

    MongoDB版本3.4.10 (应用程序正在使用Meteor框架)

    目标 :根据运行时的需要,将ID引用的文档聚合到包含文档中。

    我有 Materials ,请 Models ,和 Catalog 包含以下文档的集合:

    材料

     { "_id" : "cf4KgXw7ZK6ukdzR7", "name" : "parquet_wood_mahogany" }
    

    模型

    {
      "_id" : "Mwp5eYYZ4GZzvZuoK",
      "name" : "top_square_chamfered",
      "type" : "top"
    }
    {
      "_id" : "CqhS2m2RcLZ2Bm4eb",
      "name" : "skirt_square",
      "type" : "skirt"
    }
    {
      "_id" : "dYP22ajALnWBwpBj2",
      "name" : "leg_square",
      "type" : "leg"
    }
    

    目录

    {
      "_id" : "EcRGzPAq79giYKrbY",
      ...,
      "specs" : {
        ...,
        "models" : [
          {
            "mesh" : "Mwp5eYYZ4GZzvZuoK",
            "material" : "cf4KgXw7ZK6ukdzR7"
          },
          {
            "mesh" : "CqhS2m2RcLZ2Bm4eb",
            "material" : "cf4KgXw7ZK6ukdzR7"
          },
          {
            "mesh" : "dYP22ajALnWBwpBj2",
            "material" : "cf4KgXw7ZK6ukdzR7"
          }
        ]
      }
    }
    

    渴望的 聚合后返回的文档格式:

    {
      "_id" : "EcRGzPAq79giYKrbY",
      ...,
      "specs" : {
        "dimensions" : {
          ...,
        },
        "models" : [
          {
            "mesh" : {
              "_id" : "Mwp5eYYZ4GZzvZuoK",
              "name" : "top_square_chamfered",
              "type" : "top"
            },
            "material" : {
              "_id" : "cf4KgXw7ZK6ukdzR7",
              "name" : "parquet_wood_mahogany"
            }
          },
          {
            "mesh" : {
              "_id" : "CqhS2m2RcLZ2Bm4eb",
              "name" : "skirt_square",
              "type" : "skirt"
            },
            "material" : {
              "_id" : "cf4KgXw7ZK6ukdzR7",
              "name" : "parquet_wood_mahogany"
            }
          },
          {
            "mesh" : {
              "_id" : "dYP22ajALnWBwpBj2",
              "name" : "leg_square",
              "type" : "leg"
            },
            "material" : {
              "_id" : "cf4KgXw7ZK6ukdzR7",
              "name" : "parquet_wood_mahogany"
            }
          }
        ]
      }
    }
    

    我没有包括我的任何查询代码,因为它是如此远离标记,只是噪音。我一直想用 aggregate ,与 $lookup 组合,但我不会接近我想要的。MongoDB 3.6版 pipeline 语法将使这更容易…但我在v3.4中完全不知所措。

    如果可能的话,我希望避免使用多个数据库请求来组合这些信息。如能提供任何建议,我们将不胜感激!

    编辑:工作解决方案-

    db.catalog.aggregate([
      { "$lookup": {
        "from": 'models',
        "localField": "specs.models.mesh",
        "foreignField": "_id",
        "as": "models.mesh"
      }},
      { "$lookup": {
        "from": 'materials',
        "localField": "specs.models.material",
        "foreignField": "_id",
        "as": "models.material"
      }},
      { "$unwind": "$models.mesh" },
      { "$unwind": "$models.material" },
      { "$group":{
        "_id": "$_id",
        "title": { "$first": "$title" },
        "desc": { "$first": "$desc" },
        "thumbnail": { "$first": "$thumbnail" },
        "createdBy": { "$first": "$createdBy" },
        "createdAt": { "$first": "$createdAt" },
        "specs": { "$first": "$specs" },
        "models": { "$push": "$models" }
      }},
      { "$project": {
        "_id": "$_id",
        "title": "$title",
        "desc": "$desc",
        "thumbnail": "$thumbnail",
        "createdBy": "$createdBy",
        "createdAt": "$createdAt",
        "specs.dimensions": "$specs.dimensions",
        "specs.models": "$models",
      }}
    ])
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Ashh    8 年前

    您可以尝试以下聚合

    db.catalog.aggregate([
      { "$lookup": {
        "from": 'models',
        "localField": "specs.models.mesh",
        "foreignField": "_id",
        "as": "models.mesh"
      }},
      { "$lookup": {
        "from": 'materials',
        "localField": "specs.models.material",
        "foreignField": "_id",
        "as": "models.material"
      }},
      { "$unwind": "$models.mesh" },
      { "$unwind": "$models.material" },
      { "$group":{
        "_id": "$_id",
        "title": { "$first": "$title" },
        "desc": { "$first": "$desc" },
        "thumbnail": { "$first": "$thumbnail" },
        "createdBy": { "$first": "$createdBy" },
        "createdAt": { "$first": "$createdAt" },
        "specs": { "$first": "$specs" },
        "models": { "$push": "$models" }
      }},
      { "$project": {
        "title": "$title",
        "desc": "$desc",
        "thumbnail": "$thumbnail",
        "createdBy": "$createdBy",
        "createdAt": "$createdAt",
        "specs.dimensions": "$specs.dimensions",
        "specs.models": "$models",
      }}
    ])
    
    推荐文章