mongoose Mongo查询从相同或不同的文档中只获取选定的对象

m1m5dgzv  于 2023-04-21  发布在  Go
关注(0)|答案(2)|浏览(118)

我需要一点帮助。我有一个集合,它有一个字段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' } },
   .....,
])

这实际上返回了整个集合1的维度,以及那些ID不在集合2的productTags中的记录。
有没有人可以帮助我了解更多关于这个问题。
谢谢,索汉姆·罗伊

u0njafvf

u0njafvf1#

1.集合1与集合2联接。此阶段的输出将是具有dimensions数组的文档。
1.由于MongoDB中的$lookup stage是LEFT JOIN。要执行join,您必须使用dimensions不是空数组来过滤文档。
1.通过$reducedimensions.productTags中的嵌套数组连接到数组中,设置productTags字段。
1.使用_id存在于productTags数组中的文档过滤dimension数组。

  1. $unwind-将dimension数组解构为多个文档。
  2. $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"
  }
])

Demo @ Mongo Playground

u2nhd7ah

u2nhd7ah2#

另一种选择是:

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 example上的工作原理

相关问题