MongoDB 查询 - 仅从相同或不同文档中获取选定的对象

问题描述 投票:0回答:2

我需要一点帮助。我有一个集合,其中有一个字段 dimension 并且该字段包含不同对象的数组,如下所示:

收藏 - 1:

[
  {
    "_id": {
      "$oid": "6423cddbf4db0d397b22390a"
    },
    "dimension": [
      {
        "_id": {
          "$oid": "6423cde4f4db0d397b22390b"
        },
        "dimensionChild": "Wedding"
      },
      {
        "_id": {
          "$oid": "6423ce0af4db0d397b22390c"
        },
        "dimensionChild": "Business Casual"
      },
      {
        "_id": {
          "$oid": "6423ce18f4db0d397b22390d"
        },
        "dimensionChild": "Formal"
      }
    ]
  },
......
]

在另一个对象中,我以数组的形式从上述文档(集合 - 1)中获得了可用的 id,如下所示:

收藏 - 2:

[
  {
    "productTags": [
      {
        "$oid": "6423ce0af4db0d397b22390c" // id from above doc
      },
      {
        "$oid": "6423b723f226c91a55d756bc" // id from different document
      }
    ]
  }
]

现在我需要一些如下数据:

[
  {
    "_id": {
      "$oid": "6423ce0af4db0d397b22390c"
    },
    "dimensionChild": "Business Casual"
  },
  {
    "_id": {
      "$oid": "6423b723f226c91a55d756bc"
    },
    "dimensionChild": "Business Casual 2"
  }
]

我正在使用聚合管道来获取它,我的尝试如下:

await MODEL.aggregate([
   .....,
    {'$lookup': { "from": 'TEAGET_COLLECTION', "localField": 'productTags', "foreignField": 'dimension._id', as: 'dimensions' } },
   .....,
])

这实际上返回了我整个“Collection - 1”的维度,以及那些 id 不存在于“Collection - 2”的

productTags
中的记录。

有人可以帮我了解更多有关此查询的信息吗?

谢谢, 索汉·罗伊

node.js mongodb mongoose mongodb-query aggregation-framework
2个回答
1
投票
  1. 集合 1 与集合 2 连接。此阶段的输出将是带有

    dimensions
    数组的文档。

  2. 由于 MongoDB 中的

    $lookup
    阶段是 LEFT JOIN。要执行连接,您必须使用
    dimensions
    不是空数组来过滤文档。

  3. 通过

    productTags
    将嵌套数组从
    dimensions.productTags
    连接到数组中来设置
    $reduce
    字段。

  4. dimension
    存在于
    _id
    数组中的文档过滤
    productTags
    数组。

  5. $unwind
    - 将
    dimension
    数组解构为多个文档。

  6. $replaceWith
    - 将输入文档替换为
    dimension
    对象。

db.col1.aggregate([
  {
    "$lookup": {
      "from": "col2",
      "localField": "dimension._id",
      "foreignField": "productTags",
      as: "dimensions"
    }
  },
  {
    $match: {
      dimensions: {
        $ne: []
      }
    }
  },
  {
    $set: {
      productTags: {
        $reduce: {
          input: "$dimensions",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              "$$this.productTags"
            ]
          }
        }
      }
    }
  },
  {
    $set: {
      dimension: {
        $filter: {
          input: "$dimension",
          cond: {
            $in: [
              "$$this._id",
              "$productTags"
            ]
          }
        }
      }
    }
  },
  {
    $unwind: "$dimension"
  },
  {
    $replaceWith: "$dimension"
  }
])

演示@Mongo Playground


0
投票

另一种选择是:

db.collection1.aggregate([
  {$lookup: {
      from: "collection2",
      localField: "productTags",
      foreignField: "dimension._id",
      as: "collection2"
  }},
  {$project: {
      dimension: {$filter: {
          input: "$dimension",
          cond: {$in: [
              "$$this._id",
              {$getField: {input: {$first: "$collection2"}, field: "productTags"}}
          ]}
      }}
  }},
  {$unwind: "$dimension"},
  {$replaceRoot: {newRoot: "$dimension"}}
])

查看它在 playground 示例中的工作原理

© www.soinside.com 2019 - 2024. All rights reserved.