猫鼬骨料

时间:2019-04-20 15:02:15

标签: node.js mongoose aggregate mongoose-schema

我需要有关Mongo,Mongoose和Node.js的帮助。

在下面的代码中,我想加入carrinho和produtos集合,以在同一数组/对象中检索produtos _id,价格和说明。

我的Carrinho模式

nginx.conf

我的产品架构

 const Carrinho = new mongoose.Schema(
   {
     title: {
       type: String,
     },
     produtos: [{
       price: Number,
       produto: { type: mongoose.Schema.Types.ObjectId, ref: 
 "Produtos" }
     }
     ],
     total: {
       type: Number,
     },
   },
     {
       timestamps: true


     })

在阅读了聚合文档之后,这是我所拥有的最好的

   const Produtos = new mongoose.Schema(
     {
description: {
  type: String,
  required: true,
},
gtin: {
  type: String,
  required: true,
  unique: true,
},
thumbnail: {
  type: String,

},
price: {
  type: Number,
}
     },
     {
       timestamps: true
     }
   )

返回的是什么(结果)

    Carrinho.aggregate([
  { "$match": { "_id": mongoose.Types.ObjectId(req.params.id) } },
  {
    "$lookup": {
      "from": "produtos",
      "localField": "produtos._id",
      "foreignField": "_id",
      "as": "produtosnocarrinho"
    }
  },
  {
    "$addFields": {
      "total": {
        "$reduce": {
          "input": "$produtos",
          "initialValue": 0,
          "in": { "$add": ["$$value", "$$this.price"] }
        }
      }
    }
  }
]).exec((err, data) => {
  if (err) res.json(err)

  res.json(data)
});

希望你们能帮我这个忙。

非常感谢!

1 个答案:

答案 0 :(得分:0)

以下查询将有所帮助:

 models.Carrinho.aggregate(
    [     
        { "$match": { "_id": mongoose.Types.ObjectId(req.params.id) } },
        {
            "$lookup": {
              "from": "produtos",
              "localField": "produtos._id",
              "foreignField": "_id",
              "as": "produtosnocarrinho"
            }
          },
          {
            "$addFields": {
              "total": {
                "$reduce": {
                  "input": "$produtos",
                  "initialValue": 0,
                  "in": { "$add": ["$$value", "$$this.price"] }
                }
              }
            }
          },
          {$unwind : '$produtos'},
          {$unwind : '$produtosnocarrinho'},
          {$redact: { $cond: [{
                                  $eq: [
                                         "$produtos._id",
                                         "$produtosnocarrinho._id"
                                       ]
                                },
                                "$$KEEP",
                                "$$PRUNE"
                              ]
                      }
            },
            { $project: {
                     _id : 1,
                     title : 1,
                     produtosData : {
                        _id : "$produtos._id",
                        price : "$produtos.price",
                        description : "$produtosnocarrinho.description"
                     },
                     total : 1,
                     createdAt:  1,
                     updatedAt : 1
                }
           },
           {
              $group : {
                    _id : {
                        _id : '$_id',
                        title : '$title',
                        total : '$total',
                        createdAt  : '$createdAt',
                        updatedAt : '$updatedAt'
                    },
                    produtosData: {$push: "$produtosData" }
              }
           },
           { $project: {
                    _id  : '$_id._id',
                    title : '$_id.title',
                    total : '$_id.total',
                    createdAt  : '$_id.createdAt',
                    updatedAt : '$_id.updatedAt',
                    produtosData:  '$produtosData'
                }
           }
    ]).exec((err, data) => {
        if (err) res.json(err)

        res.json(data)
      });


Output : 
[{
    "_id": "5cbc42c24502a7318952d7b2",
    "title": "Carrinho do Lucas",
    "total": 60.300000000000004,
    "createdAt": "2019-04-21T10:15:30.629Z",
    "updatedAt": "2019-04-21T10:15:30.629Z",
    "produtosData": [{
        "_id": "5cafead2bc648978100d7698",
        "price": 20.1,
        "description": "HASBRO MR. POTATO HEAD MALETA DE PEÇAS"
    }, {
        "_id": "5cae911adf75ac4d3ca4bcb6",
        "price": 20.1,
        "description": "AÇÚCAR REFINADO UNIÃO 1KGS"
    }, {
        "_id": "5cb0f0adc5fb29105d271499",
        "price": 20.1,
        "description": "REPELENTE EXPOSIS INFANTIL SPRAY"
    }]
}]

性能取决于产品与Lookup Query匹配的数据。我们正在执行两次Unwind。