【问题标题】:aggregation lookup and match a nested array聚合查找并匹配嵌套数组
【发布时间】:2020-09-18 00:14:18
【问题描述】:

您好,我正在尝试加入两个收藏...

#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']
                                    },
                                }
                             },
                            ]
                        }
                    }

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

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:

    你可以试试,

    • $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

    【讨论】:

    • 这是预期的输出,但你缺少一些东西, products.categories 有的是值的_id
    • 是的,还是很糟糕,products.categories 包含值 _id,因此在您的示例中,它将具有例如 categories['1','2']
    • 正是缺少的,其余的我认为是完美的
    【解决方案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

    【讨论】:

    • 我不是 node.js 的人。我尽力帮助你,如果有任何错误,请告诉我
    猜你喜欢
    • 1970-01-01
    • 2021-12-31
    • 2020-12-18
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 2020-06-29
    相关资源
    最近更新 更多