【问题标题】:Mongoose many to many population with uni-directional references单向引用的猫鼬多对多种群
【发布时间】:2014-02-08 06:30:23
【问题描述】:

我有以下用于表示多对多关系的模式:

var CategorySchema = new Schema({
  title: {type: String},    
});
mongoose.model('Category', CategorySchema);

var ProductSchema = new Schema({
  title: {type: String},
  categories: [
    {
      type: Schema.ObjectId,
      ref: 'Category'
    }
  ]
});
mongoose.model('Product', ProductSchema );

当我查询类别或产品时,我希望能够在结果中获得所有链接的文档。

在查询产品时填充类别很简单:

Product.find().populate('categories').exec(...)

但是如何从类别方面做到这一点?我知道我可以将 ObjectId ref 数组添加到 CategorySchema 中的 Product 文档中。但是我想避免双向引用(我不想维护它,并且有不一致的风险)。

编辑:这是我实施的解决方案

/**
 * List all Categories
 */
exports.all = function (req, res) {
  //Function needed in order to send the http response only once all
  //the categories' product has been retrieved and added to the returned JSON document.
  function sendResponse(categories) {
    res.json(categories);
  }

  AppCategory.list(function (err, categories) {
    if (err) {
      errors.serverError();
    } else {
      _.forEach(categories, function (category, index) {
        category.products = [];
        Product.byCategory(category._id, function (err, products) {
          category.products= category.products.concat(products);
          if (index === categories.length - 1) {
            sendResponse(categories);
          }
        });
      });
    }
  });
};


ProductSchema.statics = {
  byCategory: function (categoryId, callback) {
    this.find({'categories': categoryId})
      .sort('-title')
      .exec(callback);
  }
};

【问题讨论】:

    标签: node.js mongodb mongoose many-to-many schema


    【解决方案1】:

    您可能不想这样做。 :-) 我猜一个产品可能属于一些相当少的类别,但一个类别可能有数千种产品。在这种情况下,从效率的角度来看,尝试执行 Category.populate('products') 是行不通的。您将使用大量内存,无法直接进行分页,当产品属于多个类别时将重复的产品数据加载到内存中等。最好通过直接查询产品集合来加载类别中的产品.你可以很容易地按类别过滤Product.find({'categories._id': $in: arrayOfCategoryIds}})

    【讨论】:

    • 感谢您的回答。我实现了你描述的东西。我更新了我的问题。现在我可以检索填充了所有产品的类别。在我的用例中,我需要按类别检索所有产品的列表,而不是仅在一个 JSON 文档中获取。实际上不会有这么多产品,可能最多只有几百个。
    猜你喜欢
    • 2018-02-10
    • 2016-07-31
    • 1970-01-01
    • 2019-09-13
    • 2017-06-02
    • 2021-05-10
    • 1970-01-01
    • 2016-07-11
    • 2021-06-22
    相关资源
    最近更新 更多