首页 > 解决方案 > 填充聚合两个不同集合的 Mongoose 虚拟

问题描述

我的应用程序目前有一些复杂的情况,这给我带来了各种各样的问题。作为应用程序的一部分,我们正在构建食谱,并且食谱由成分制成(这里简称为“食物”,因为它们也可以单独使用)。我们有一组静态配方和一个动态(“用户”)配方,它们在与用户关联时从静态版本复制。从技术上讲,这些食谱都存在于一个集合中,但使用了鉴别器。

但是,对于食品,我们有一个从第三方购买的数据库,但我们也可能需要添加我们自己的食品。因为来自第三方数据库的更新可能需要覆盖该数据库,所以我们需要将来自第三方的食物与我们创建的食物分开。所以这里我们需要两个完全独立的集合,我们称之为“foodsTP”和“foodsAdmin”。但是,因为从用户的角度来看,这些功能应该完全相同,所以我们不希望前端关心食物来自哪个集合。

直接获取食物时,这不是问题。我们在食谱上有一个虚拟吸气剂,它结合了两个系列的食物:

RecipeBaseSchema.virtual('foods').get(function get() {
  return this.foodsTP.concat(this.foodsAdmin);
});

但是,一旦将食物添加到食谱中,获取食谱的 API 请求不会正确填充食物信息。我已经看过这个关于 Virtual Populate 的文档,但它似乎不是我需要的。我的虚拟在这里不仅仅是对另一个集合的引用,它还积极地结合了对另外两个集合的引用。当我们提取这个组合的食物数组时,我们应该能够从两个集合中获取所有食物信息。但是,这是我在控制台中遇到的错误:

如果要填充虚拟,则必须设置 localField 和 foreignField 选项

有什么办法可以用我的组合虚拟阵列来做到这一点?

编辑:这是一个简化的配方模式。

const RecipeBaseSchema = new Schema({
  name: {
    type: String,
    required: true,
  },
  foodsTP: [{
    quantity: {
      type: Number,
      default: 1,
    },
    measureUnit: String,
    food: {
      type: Schema.Types.ObjectId,
      ref: 'Food',
    },
  }],
  foodsAdmin: [{
    quantity: {
      type: Number,
      default: 1,
    },
    measureUnit: String,
    food: {
      type: Schema.Types.ObjectId,
      ref: 'FoodAdmin',
    },
  }],
  dateAdded: Date,
  dateModified: Date,
},
{
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
}); // options

const RecipeUserSchema = new Schema({});
const RecipeAdminSchema = new Schema({});

接口查询:

export function getRecipeUser(params) {
  params.populate = [
    {
      path: 'foods',
      populate: { path: 'food' },
    },
  ];
  params.query = {
    _id: params.recipeId,
  };

  return apiCall('get', `/recipeuser`, omit(params, ['recipeId'])).then(
    recipesUser => {
      console.log(recipesUser);
      return recipesUser[0];
    }
  );
}

标签: mongodbmongoose

解决方案


推荐阅读