如何在 Sequelize 中对 belongsToMany 关联进行***查询?

Posted

技术标签:

【中文标题】如何在 Sequelize 中对 belongsToMany 关联进行***查询?【英文标题】:How do I make a top level query on belongsToMany association in Sequelize? 【发布时间】:2018-03-30 11:35:23 【问题描述】:

我需要获取属于某个帖子的所有标签。

首先,我通过belongsToMany 关联管理帖子和标签,就像表post_tag 一样。这些模型的构建如下:

Post.belongsToMany(Tag, 
  as: 'tags',
  through: 
    model: PostTag,
    unique: true,
  ,
  foreignKey: 'post_id',
  constraints: true
);

Tag.belongsToMany(Post, 
  as:'posts',
  through: 
    model: PostTag,
    unique: true,
  ,
  foreignKey: 'tag_id',
  constraints: true
);

然后,我写了这样一个很好的工作声明:

Post.findAll(
  include: [
    model: Tag, as: 'tags',
    attributes: ['id','name'],
    through: attributes:[]
  ]
)
//JSON result 
[
   
    "title": "Post title 1",
    "tags": [
      "id":1, "name": "tagA",
      "id":2, "name": "tagB"
    ]
  ,
   
    "title": "Post title 2",
    "tags": [
      "id":1, "name": "tagA",
      "id":3, "name": "tagC"
    ]
  
]

当我试图过滤 tagA 的帖子时,我仍然得到了 2 个与上面相同的帖子。但是tagBtagC 在嵌套属性tags 中丢失了:

    Post.findAll(
      include: [
        model: Tag, as: 'tags',
        attributes: ['id','name'],
        through: attributes:[],
        where: name:'tagA' // <--- Add filter here
      ]
    )
    //JSON result 
    [
       
        "title": "Post title 1",
        "tags": [
          "id":1, "name": "tagA"  // <-- tagB was gone
        ]
      ,
       
        "title": "Post title 2",
        "tags": [
          "id":1, "name": "tagA"  // <-- tagC was gone
        ]
      
    ]

我阅读了Sequelize document,它指导我们将where 移至顶层,但它仅适用于hasMany 关联。

   Post.findAll(
      where: '$tags.name$':'tagA' // <--- move query to top here follow the guide
      include: [
        model: Tag, as: 'tags',
        attributes: ['id','name'],
        through: attributes:[],            
      ]
    )

有什么方法可以在结果中保留tagBtagC

【问题讨论】:

github.com/sequelize/sequelize/issues/7541 标签需要一个ID!一切都会解决 或“改为使用属性: exclude: ['id'] ,排除id(如果你的mysql表没有id列)” 我还在属性中附加了 id 列:["id", "name"](如您所见,我已经更新了 JSON RESULT),但它不起作用 【参考方案1】:

Post.findAll where "TagA" 返回 id post 然后每个循环 > 获取完整的信息,包括里面的标签!

【讨论】:

我更喜欢使用急切加载而不是使用延迟加载导致查询时间。如果没有解决方案,我会试一试。

以上是关于如何在 Sequelize 中对 belongsToMany 关联进行***查询?的主要内容,如果未能解决你的问题,请参考以下文章

Sequelize js - 限制和排序错误

在 forEach 问题中对事务进行后续处理

在 forEach 问题中对交易进行序列化。

sequelize + sequelize-hierarchy:如何在每个级别强制执行唯一的组织名称?

如何在 Sequelize 中创建关联

如何在 Sequelize 中设置必填字段?