【问题标题】:Sequelize filter nested includesSequelize 过滤器嵌套包括
【发布时间】:2019-12-17 20:11:24
【问题描述】:

我有 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 的列,而这个错误对我来说没有意义。

我是否在这里遗漏了一个重点,或者这应该可以工作,但我可能设置错误?

【问题讨论】:

    标签: sql node.js sequelize.js


    【解决方案1】:

    sequelize manual 的 Eager loading 部分似乎表明您会这样做:

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

    【讨论】:

      【解决方案2】:

      好的,所以我再次阅读了文档,并意识到我的第二个表 TermRelationship 仅用于映射,实际上有一种非常酷的方法来实现 N:M 关系在Belongs-To-Many associations chapter 中详细解释。

      我几乎使用belongsToMany 函数设计了模型,例如:

      // 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"
          });
      

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

      然后一个简单的伎俩(请注意include中的required: false

        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 }]
            }
          ]
        })
      

      这几乎是我的第一个可能的示例,它返回 null 而不是带有空 TermTaxonomy 数组的帖子。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-12
        • 2017-07-27
        • 1970-01-01
        • 2017-08-27
        • 2021-02-09
        • 2021-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多