嵌套过滤器嵌套包括

时间:2019-12-16 16:53:15

标签: sql node.js sequelize.js

我有3张桌子

Post: post_id, name

TermRelationship: post_id, term_taxonomy_id

TermTaxonomy: term_taxonomy_id, name

关系:

PostTermRelationship是一对多

TermRelationshipTermTaxonomy是一对一

我正在寻找一个包含所有此类数据的帖子,一切都很好:

  Post.findOne({
    where: { post_id: 351043 },
    include: [
      {
        model: TermRelationships,
        include: [{ model: TermTaxonomy }]
      }
    ]
  })

现在的问题是,我不需要全部TermRelationships,我只想要将name设置为RandomName 的那些

我尝试了很多在互联网上找到的方法,但是没有任何效果,我最后一次尝试就是这样

  Post.findOne({
    where: { post_id: 351043 },
    include: [
      PostMeta,
      {
        model: TermRelationships,
        include: [{ model: TermTaxonomy, where: { name: "RandomName" } }]
      }
    ]
  })

,但这将返回null,而不是带有空TermRelationship数组的帖子。

我最好的猜测是,我应该将where子句放在较高级别,然后执行以下操作:

  Post.findOne({
    where: { post_id: 351043 },
    include: [
      PostMeta,
      {
        model: TermRelationships,
        include: [{ model: TermTaxonomy }],
        where: { "$TermTaxonomy.name$": "RandomName" }
      }
    ]
  })

但它返回Unknown column 'TermTaxonomy.name' in 'where clause'

TermTaxonomy上有一个名为name的列,该错误对我来说没有意义。

我在这里遗漏了一个要点吗?或者这应该起作用,并且我可能设置错误了吗?

2 个答案:

答案 0 :(得分:0)

sequelize manual的“渴望加载”部分似乎表明您会这样做:

  Post.findOne({
    where: { post_id: 351043 },
    include: [
      {
        model: TermRelationships,
        where: { name: "RandomName" }
      }
    ]
  })

答案 1 :(得分:0)

好的,所以我再次阅读了文档,意识到我的第二张表TermRelationship仅用于映射,实际上有一种很酷的方法来实现{{1} 3}}。

我几乎使用N:M函数设计模型,例如:

belongsToMany

进行双向绑定很重要,因为如果不这样做,Sequelize会尝试“猜测”列名和键,有时这会导致意外错误。

然后有一个简单的窍门(请注意// this will map Post's primary key to the "post_id" column of the TermRelationships table Post.belongsToMany(TermTaxonomy, { foreignKey: "post_id", through: "TermRelationships" }); // this will map TermTaxonomy primary key to the "term_taxonomy_id" column of the TermRelationships table TermTaxonomy.belongsToMany(Post, { foreignKey: "term_taxonomy_id", through: "TermRelationships" }); 中的required: false

include

请注意,第一种方法实际上还不错,但是我需要这样的东西:

  Post.findOne({
    where: { ID: 351043 },
    include: [{ model: TermTaxonomy, where: { name: "RandomName" }, required: false }]
  })

这几乎是我第一个可能的示例,它返回 Post.findOne({ where: { post_id: 351043 }, include: [ PostMeta, { model: TermRelationships, include: [{ model: TermTaxonomy, where: { name: "RandomName" }, required: false }] } ] }) 而不是带有TermTaxonomy空数组的帖子。

此处的关键是将null添加到required: false,这样它将返回一个元素数组,其中一些元素include,然后您可以说需要这些元素不是null(比我发现的其他解决方案难得多)