【问题标题】:Aggregate data and populate in one request聚合数据并在一个请求中填充
【发布时间】:2022-01-01 12:11:09
【问题描述】:

我对 MongoDB 中的populate 有点疑惑。

我有一个架构:


import { Schema, Document, model } from "mongoose";

export interface ProductGroupType {
    id: Schema.Types.ObjectId,
    title: String,
    name: String,
    description: String,
}

const ProductGroupSchema: Schema<Document<ProductGroupType>> = new Schema({
    title: { type: String, trim: true },
    name: { type: String, trim: true },
    description: { type: String, trim: true },
}, { collection: "productGroups", timestamps: true });

export const ProductGroupModel = model('ProductGroup', ProductGroupSchema);

和产品

import { Schema, Document, model } from "mongoose";
import { plugin as autocomplete } from 'mongoose-auto-increment';

const ProductSchema: Schema<Document<IProduct>> = new Schema({
    article: Number,
    name: String,
    category: { type: Schema.Types.ObjectId, ref: 'ProductCategory' },
    group: { type: Schema.Types.ObjectId, ref: 'ProductGroup' },
    price: { type: Number, default: 0 },
    discount: { type: Number, default: 0 },
    stock: {
        available: { type: Number, default: 0 },
        reserved:  { type: Number, default: 0 },
    },
    images: [Object],
    description: String,
    productDetails: Object,
}, { collection: "products", timestamps: true });

ProductSchema.plugin(autocomplete, {
    model: 'Product',
    field: 'article',
    startAt: 10000,
});
export const ProductModel = model('Product', ProductSchema);

我需要通过“组”字段对 MongoDB 端数据进行请求和分组。 我可以这样:

await ProductModel.aggregate([
            { $match: { category: Types.ObjectId(queryCategory.id) } },
            { 
                $group: { 
                    _id: '$group', 
                    products: {
                        $push: {
                            id: '$_id',
                            name: '$name',
                            article: '$article',
                            price: '$price',
                            discount: '$discount',
                            description: '$description',
                            group: '$groupName',
                        }
                    },
                    count: { $sum: 1 }, 
                } 
            },
]);

但这里的输出是:

[
  { _id: 61969583ad32e113f87d0e99, products: [ [Object] ], count: 1 },
  {
    _id: 61993fff452631090bfff750,
    products: [ [Object], [Object] ],
    count: 2
  }
]

几乎是我需要的,但我一直在玩人口,我无法让它与聚合框架一起工作。

我已经尝试使用“查找”运算符,但它返回一个空数组并且不想工作。

这就是我想让它工作的方式:

const products: Array<IProduct> = await ProductModel.aggregate([
            { $match: { category: Types.ObjectId(queryCategory.id) } },
            { 
                $group: { 
                    _id: '$group', 
                    products: {
                        $push: {
                            id: '$_id',
                            name: '$name',
                            article: '$article',
                            price: '$price',
                            discount: '$discount',
                            description: '$description',
                            group: '$groupName',
                        }
                    },
                    count: { $sum: 1 }, 
                } 
            },
            {
                $lookup: {
                    "from": "productGroups",
                    "localField": "group",
                    "foreignField": "_id",
                    "as": "groupName"
               },
            },
        ]);

是否可以获得与我现在相同的结果但填充在同一个查询组字段中?

到目前为止,我设法将它作为第二个请求填充的唯一方法:

await ProductGroupModel.populate( products.map( (product: any) => {

            return {
                _id: new ProductGroupModel(product),
                products: product.products,
                count: product.count,
            }
        } ), { "path": "_id" } )

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    在 MongoDB 聚合管道中,$group 阶段仅传递在阶段中明确声明的那些字段。

    在您显示的同一管道中,$group 阶段传递的文档将包含以下字段:

    • _id
    • 产品
    • 计数

    当执行器到达$lookup 阶段时,没有一个文档包含名为group 的字段。

    但是,group 字段中先前包含的值仍然存在,在 _id 字段中。

    $lookup 阶段,使用

    "localField": "_id",
    

    根据该值查找文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-28
      • 2021-10-22
      • 1970-01-01
      • 2019-04-23
      • 2021-04-23
      相关资源
      最近更新 更多