聚合查找并匹配嵌套数组

时间:2020-09-17 15:23:50

标签: mongodb mongoose aggregation-framework

你好,我想加入两个收藏夹...

#COLLECTION 1

const valuesSchema= new Schema({
    value: { type: String },
})

const categoriesSchema = new Schema({
    name: { type: String },
    values: [valuesSchema]
    })

mongoose.model('categories', categoriesSchema )

#COLLECTION 2

const productsSchema = new Schema({
    name: { type: String },
    description: { type: String },
    categories: [{
       type: mongoose.Schema.Types.ObjectId,
       ref: 'categories',
        }]
    })

mongoose.model('productos', productsSchema )

现在,我假装要做的就是加入这些集合并获得类似这样的输出。

#示例产品文档

{
    name: 'My laptop',
    description: 'Very ugly laptop',
    categories: ['5f55949054f3f31db0491b5c','5f55949054f3f31db0491b5b'] // these are _id of valuesSchema
}

#预期输出

{
    name: 'My laptop',
    description: 'Very ugly laptop',
    categories: [{value: 'Laptop'}, {value: 'PC'}]
}

这是我尝试过的。

                 {
                        $lookup: {
                            from: "categories",
                            let: { "categories": "$categories" },
                            as: "categories",
                            pipeline: [
                             {
                                $match: {
                                    $expr: {
                                        $in: [ '$values._id','$$categories']
                                    },
                                }
                             },
                            ]
                        }
                    }

但是此查询不匹配...有什么帮助吗?

2 个答案:

答案 0 :(得分:3)

您可以尝试

  • $lookup带有类别
  • $unwind解构values数组
  • $match类别ID和值ID
  • $project以显示必填字段
db.products.aggregate([
  {
    $lookup: {
      from: "categories",
      let: { cat: "$categories" },
      as: "categories",
      pipeline: [
        { $unwind: "$values" },
        { $match: { $expr: { $in: ["$values._id", "$$cat"] } } },
        {
          $project: {
            _id: 0,
            value: "$values.value"
          }
        }
      ]
    }
  }
])

Playground

答案 1 :(得分:2)

由于您尝试使用不相关的查询,因此我很感激,您可以使用$unwind轻松地对数组进行平整,然后对$match进行平整。要重新组合数组,请使用$group$reduce有助于在每个数组上移动并存储一些特定值。

 [
  {
    $lookup: {
      from: "categories",
      let: {
        "categories": "$categories"
      },
      as: "categories",
      pipeline: [
        {
          $unwind: "$values"
        },
        {
          $match: {
            $expr: {
              $in: [
                "$values._id",
                "$$categories"
              ]
            },
            
          }
        },
        {
          $group: {
            _id: "$_id",
            values: {
              $addToSet: "$values"
            }
          }
        }
      ]
    }
  },
  {
    $project: {
      categories: {
        $reduce: {
          input: "$categories",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$this.values",
              "$$value"
            ]
          }
        }
      }
    }
  }
]

工作Mongo template