使用Sequelize在多个表之间创建“多对多”关系

时间:2019-04-03 11:00:16

标签: javascript node.js sql-server typescript sequelize.js

我在MSSQL中已经有一个架构(下图),
我有一个搜索表,每个搜索由一些元数据和3种类型的过滤器组成(每个搜索可以是多个过滤器),并且我有一个“多对多”表来将所有类型的过滤器连接到搜索。
我想使用Sequelize来查询我的搜索并获取每个过滤器,但找不到任何方法可以将多个过滤器连接到我的搜索表以使用连接表(过滤器)进行建模

DB Design

搜索:包含搜索的元数据和搜索ID。
过滤器:包含搜索ID,并使用过滤器ID和过滤器类型(枚举:“ range”,“ datetime”,“ exact”)将其匹配以进行过滤。
范围过滤器,日期时间过滤器,精确过滤器:过滤器本身及其信息。

如果不可能一起查询它们,我认为可以在这些表上创建视图并在Sequelize中为其创建模型,但这可能(但效率可能较低),但是我不确定也可以做到这一点。

是否可以对我想要的方式进行建模?如果是的话,如何创建此连接?
谢谢!

2 个答案:

答案 0 :(得分:2)

在Sequelize中,当您在中间表中拥有除外键之外的其他属性时,您也必须定义其模型。
根据上述架构,您必须具有所有表的模型,包括中间的表(过滤器)。 通过这种方式分配关联:

//associations from search model
SearchesModel.belongsToMany(RangesFiltersModel, {through: FiltersModel, foriegnKey: 'filter_search_id', otherKey: 'filter_id'});
SearchesModel.belongsToMany(ExactFiltersModel, {through: FiltersModel, foriegnKey: 'filter_search_id', otherKey: 'filter_id'});
SearchesModel.belongsToMany(DatetimeFiltersModel, {through: FiltersModel, foriegnKey: 'filter_search_id', otherKey: 'filter_id'});

//associations from filters
RangesFilterModel.belongsToMany(SearchesModel, {through: FiltersModel, foreignKey: 'filter_id', otherKey: 'filter_search_id'});
ExactFilterModel.belongsToMany(SearchesModel, {through: FiltersModel, foreignKey: 'filter_id', otherKey: 'filter_search_id'});
DatetimeFilterModel.belongsToMany(SearchesModel, {through: FiltersModel, foreignKey: 'filter_id', otherKey: 'filter_search_id'});

现在,假设我有一个搜索对象:

search.getRangesFilterModels({through: {filterType: 'range'}});
search.getDatetimeFilterModels({through: {filterType: 'datetime'}});
search.getExactFilterModels({through: {filterType: 'exact'}});

要检索每个对象包含所有关联过滤器的所有搜索对象时,可以通过以下方式查询:

SearchesModel.findAll({
    include: [{
        ExactFilterModel,
        through: {filterType: 'exact'}
    }, {
        DatetimeFilterModel,
        through: {filterType: 'datetime'}
    }, {
        RangesFilterModel,
        through: {filterType: 'range'}
    }]
});

P.S。确切的代码可能不起作用,但是概念是相同的。希望这对您有帮助。有关更多信息,请单击参考中的链接。 参考:Sequelize Associations

答案 1 :(得分:0)

enter image description here

也许可以将上面的设计与两个表一起使用,一个是搜索,另一个是引用搜索的过滤器,并根据过滤器类型在过滤器中添加大小写。

示例:-

如果类型是精确的情况,则仅选择key_exactvalue列。

当类型为range(int / date)的情况下,然后使用range_datatype选择相应的转换/转换(最小范围和最大范围)

解决方案2:-

create view VW_Filters as 

select filter_id,'Range' as filter_type,....[other columns]
from ranges_filters

union

select filter_id,'Exact' as filter_type,....[other columns]
from ranges_filters


union

select filter_id,'Datetime' as filter_type,....[other columns]
from ranges_filters

然后,您需要在过滤器表的顶部创建一个视图,然后在filter_id和filter_type上与主过滤器表结合以获取搜索条件所需的过滤器。