使用 sequelize N:M 关联实现“平坦”结果的“正确”方法是啥

Posted

技术标签:

【中文标题】使用 sequelize N:M 关联实现“平坦”结果的“正确”方法是啥【英文标题】:What is the "correct" way to realize a "flat" result using sequelize N:M associations使用 sequelize N:M 关联实现“平坦”结果的“正确”方法是什么 【发布时间】:2015-10-15 17:55:08 【问题描述】:

我有一个产品数据库,其中包含一些具有 1-n 个类别的产品。我的产品存储在products 表中,类别存储在categories 中,关联存储在productCategoryRel 中。现在我的愿望是,当我使用Product.find() 获得产品时,接收包含categories 属性的结果,其中包含categories 表中的数据,没有任何其他嵌套属性。

目前这是我目前得到的:


  "id": 1,
  "title": "Testproduct",
  "categories": [
    
      "id": 1,
      "title": "Testcategory",
      "productCategoryRel": 
        "category_id": 1,
        "product_id": 1
      
    
  ]

所以我的product 包含一个属性categories,这很好,但categories 还包含我想要避免的productCategoryRel 表中的所有数据。我已经像地狱一样在谷歌上搜索,研究了文档等等,我不确定我是否有可能实现我想要实现的目标。

这就是我定义我的(测试)模型的方式:

let ProductCategoryRel = sequelize.define('productCategoryRel', );

let Category = sequelize.define('category', 
    title: Sequelize.STRING
);

let Product = sequelize.define('product', 
    title: Sequelize.STRING
, 
    defaultScope: 
        include: [
            model: Category
        ]
    
);

还有关联:

Product.belongsToMany(Category, 
    through: ProductCategoryRel,
    foreignKey: 'product_id',
);

Category.belongsToMany(Product, 
    through: ProductCategoryRel,
    foreignKey: 'category_id',
);

ProductCategoryRel.hasMany(Product, foreignKey: 'id');
ProductCategoryRel.hasMany(Category, foreignKey: 'id');

而我想要的结果很简单:


  "id": 1,
  "title": "Testproduct",
  "categories": [
    
      "id": 1,
      "title": "Testcategory"
    
  ]

那么这甚至可能吗?我如何需要我来改变我的关联?我已经尝试了一些奇怪的 hasMany/belongsTo 组合,但没有成功。

我正在使用 Sequelize 3.12.1。

【问题讨论】:

【参考方案1】:

试试这样的(可能会有一些错误,但如果你给我反馈我们会解决问题):

Product.findOne(
    where: 
      id: yourProductId
    ,
    include: [
      model : Category,
      order: [['id','desc']],
      through: attributes: []
    ],
  )

attributes 属性允许您选择要显示的数据。它也可以在包含的模型中使用。

更多文档http://docs.sequelizejs.com/en/latest/docs/querying/

【讨论】:

如果可能的话,我想避免这种情况,因为我必须明确排除每个范围内的每个属性(甚至是新属性,以防我向模型中添加一些属性),这听起来非常冗余/开销。 //编辑:顺便说一句:属性似乎只适用于包含模型(在我的情况下为类别)中指定的列,不适用于关系。我仍然看到productCategoryRel 我已经更新了我的代码 sn-p。我添加了 through: attributes: [] 应该从输出中删除 ProductCategoryRel 这会导致错误:W:\temp\node_modules\mysql\lib\protocol\Parser.js:82 throw err; ^ TypeError: Cannot set property 'productCategoryRel' of undefined 很奇怪。 如果不使用此代码,我将无能为力。我现在留下我的答案,以便其他人记录我们已经检查过的内容,并可以添加新命题的答案。 啊,你是对的。我使用 attributes[] 而不是 through: attributes: [] - 非常感谢!

以上是关于使用 sequelize N:M 关联实现“平坦”结果的“正确”方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

如何在 node.js 中使用 sequelize-npm 实现与连接表的一对多关系

附加属性 sequelize pivot n:m

Sequelize 定义 n:m 关系(import 方式)

nodejs使用sequelize操作mysql实例

使用 Sequelize 计算关联条目

使用 Sequelize.js 时在哪里定义关联/关系?