【问题标题】:How can I query an associative table with matching "where" conditions with Sequelize如何使用 Sequelize 查询具有匹配“where”条件的关联表
【发布时间】:2017-12-06 06:01:49
【问题描述】:

我正在尝试使用 sequelize 检索属于多个集合的产品。 方言是 Postgres,我使用的是 Sequelize 4.15.1

我有一个 Product 模型、一个 Collection 模型和一个关联模型 CollectionProduct。产品属于许多收藏,收藏属于许多产品。

产品型号:

const Product = sequelize.define( 'Product', {
    id: {
      type: DataTypes.STRING,
      primaryKey: true
    },
    name: DataTypes.STRING,
  } );
  Product.associate = function( models ) {
    Product.belongsToMany( models.Collection, {
      through: models.CollectionProduct
    } );
  }

收藏模型:

const Collection = sequelize.define( 'Collection', {
  name: {
    type: Sequelize.STRING
  },
  slug: {
    type: Sequelize.STRING
  },
} );
Collection.associate = function( models ) {
  Collection.belongsToMany( models.Product, {
    through: models.CollectionProduct
  } );
}

这是我的续集查询

models.Product.findAll( {
  attributes: ["id", "name"],
  include: [ {
    model: models.Collection,
    attributes: ["id", "name", "slug"],
    where: {
      slug: {
        [Op.like]: { [Op.all]: ['collection-a', 'collection-b']}
      }
    }
  } ]
} ).then( products => {
  console.log( products )
} ).catch( function ( err ) {
  console.log( err );
} );

这是生成的 postgres 查询

SELECT "Product"."id",
       "Product"."name",
       "Collections"."id" AS "Collections.id",
       "Collections"."name" AS "Collections.name",
       "Collections"."slug" AS "Collections.slug",
       "Collections->CollectionProduct"."createdAt" AS "Collections.CollectionProduct.createdAt",
       "Collections->CollectionProduct"."updatedAt" AS "Collections.CollectionProduct.updatedAt",
       "Collections->CollectionProduct"."CollectionId" AS "Collections.CollectionProduct.CollectionId",
       "Collections->CollectionProduct"."ProductId" AS "Collections.CollectionProduct.ProductId"
FROM "Products" AS "Product"
INNER JOIN ("CollectionProducts" AS "Collections->CollectionProduct"
            INNER JOIN "Collections" AS "Collections" ON "Collections"."id" = "Collections->CollectionProduct"."CollectionId") ON "Product"."id" = "Collections->CollectionProduct"."ProductId"
AND "Collections"."slug" LIKE ALL (ARRAY['collection-a',
                                         'collection-b']);

我想退回同时属于集合 A 和 B 的产品。

很遗憾,查询执行没有返回任何结果。

【问题讨论】:

  • 只是好奇:CollectionProduct的模型是你自己设置的('自定义联合表'),还是让sequelize生成?
  • 我定义了模型'use strict'; module.exports = function( sequelize, DataTypes ) { const CollectionProduct = sequelize.define( 'CollectionProduct'); return CollectionProduct; };
  • 但是 Sequelize 会自动生成关系

标签: node.js postgresql sequelize.js


【解决方案1】:

这可能会奏效。抓取所有在 collection-a id 和 collection-b id 之间相交的 productid。

select
  t1.slug as slug_ca,
  t2.slug as slug_cb,
  t1.productid
from
(
  select
    p3.slug,
    p1.id as productid
  from products p1
       inner join collectionproducts p2
         on p1.id = p2.ProductId
       inner join collections p3
         on p2.CollectionId = p3.id
  where lower(p3.slug) like '%collection-a%'
  group by 1,2
) t1
inner join
(
  select
    p3.slug,
    p1.id as productid
  from products p1
       inner join collectionproducts p2
         on p1.id = p2.ProductId
       inner join collections p3
         on p2.CollectionId = p3.id
  where lower(p3.slug) like '%collection-b%'
  group by 1,2
) t2
  on t1.productid = t2.productid
group by 1,2,3;

【讨论】:

  • 查询有效!谢谢!很难以编程方式实现它。例如,如果我想查询 x 个集合,不知道如何使其工作。
猜你喜欢
  • 2016-12-19
  • 1970-01-01
  • 2017-08-18
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 2018-08-14
相关资源
最近更新 更多