猫鼬-如何根据条件填充子文档

时间:2018-09-06 17:48:01

标签: node.js mongodb express mongoose

我是猫鼬的新手,我不知道该如何填充。 这就是我的模型:

const OrderSchema = new Schema({
    products: [{ type: Schema.Types.ObjectId, ref: 'Product' }],
    remarks: {type: String, lowercase: true}
});
mongoose.model("Order", OrderSchema);


const ProductSchema = new Schema({
   reference: {type: String}
   status: {type: Schema.Types.ObjectId, ref: 'ProductStatus'}
});
mongoose.model("Product", ProductSchema);

const ProductStatus = new Schema({
    name: {type: String}
});

const CountrySchema = new Schema({
    name: {type: String}
});
mongoose.model("Country", CountrySchema);

我有一个 getOrderById 方法

export const getOrderById = async (req, res) => {
let id = req.params.id;
try {
    await orderModel
        .findById(id)
        .populate({
            path: 'products',
            populate: {
              path: 'country',
              model: 'Country'
            }
         })
         .populate({
            path: 'products',
            populate: {
              path: 'status',
              model: 'ProductStatus'
            }
         })
        .exec(function (err, orders) {
            if (err) {
                res.send(err);
            }
            res.status(200).json(orders);
        });
} catch (error) {
    console.log(error);
}
}

现在,我想在订单中显示所有状态为“在法国收到”的产品。

1 个答案:

答案 0 :(得分:0)

首先,我想您还错过了产品架构中对国家/地区的引用,因此假设这些是您更正的架构:

const OrderSchema = new Schema({
    products: [{
        type: Schema.Types.ObjectId,
        ref: 'Product'
    }],
    remarks: {
        type: String,
        lowercase: true
    }
});
const Order = mongoose.model("Order", OrderSchema);


const ProductSchema = new Schema({
    reference: {
        type: String
    },
    country: {
        type: Schema.Types.ObjectId,
        ref: 'Country'
    },
    status: {
        type: Schema.Types.ObjectId,
        ref: 'ProductStatus'
    }
});
const Product = mongoose.model("Product", ProductSchema);

const ProductStatusSchema = new Schema({
    name: {
        type: String
    }
});
const ProductStatus = mongoose.model("ProductStatus", ProductStatusSchema);

const CountrySchema = new Schema({
    name: {
        type: String
    }
});
const Country = mongoose.model("Country", CountrySchema);

据我了解,您只想显示国家/地区名称为“法国”且ProductStatus /名称为“ Received”的产品,此类操作通过Aggregation

完成

假设您要执行一个查询,您的查询可能看起来像这样:

const getOrderById = async (req, res) => {
        let id = req.params.id.toString();
        const ObjectId = mongoose.Types.ObjectId
        try {
            const aggregationStages = [{
                $match: {
                    _id: ObjectId(id) //It is important to cast to ObjectId in aggregations
                }
            }, {
                $lookup: {
                    from: 'products',
                    let: {
                        productIds: '$products'
                    },
                    pipeline: [{
                        $match: {
                            $expr: {
                                $in: ['$_id', '$$productIds']
                            }
                        }
                    }, {
                        $lookup: {
                            from: 'countries',
                            localField: 'country',
                            foreignField: '_id',
                            as: 'country'
                        }
                    }, {
                        $lookup: {
                            from: 'productstatuses',
                            localField: 'status',
                            foreignField: '_id',
                            as: 'status'
                        }
                    }, {
                        $match: {
                            'country.name': 'France',
                            'status.name': 'Received'
                        }
                    }],
                    as: 'products'
                }
            }];
            await orderModel.aggregate(aggregationStages)
                .exec(function (err, orders) { // The return is an array btw.
                    if (err) {
                        res.send(err);
                    }
                    res.status(200).json(orders);
                });
        } catch (error) {
            console.log(error);
        }
    }

如果您觉得聚合很复杂,则可以将其拆分为较小的简单查询。随时询问您是否需要更多说明/修改。