【问题标题】:Create "Many to Many" relationship between multiple tables with Sequelize使用 Sequelize 在多个表之间创建“多对多”关系
【发布时间】:2019-08-24 21:19:54
【问题描述】:

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

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

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

是否可以按照我想要的方式建模?如果是,我该如何创建这种连接?
谢谢!

【问题讨论】:

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


    【解决方案1】:

    也许您可以使用上面的设计,其中有两个表,一个是搜索,另一个是过滤器,用于引用搜索,并根据过滤器类型在过滤器中添加案例。

    例子:-

    类型准确的情况下,只选择 key_exactvalue 列。

    类型为 range(int/date) 的情况,然后使用 range_datatype 选择相应的 cast/convert(min_range & Max_range)

    解决方案 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 上与您的主过滤器表连接,以获取搜索条件所需的过滤器。

    【讨论】:

    • 虽然有效且是一个很好的解决方案,但我的问题在于表已经存在,这使我可以通过对视图进行建模来创建该设计,而不是对现有表进行建模
    • 在答案部分查看我的其他解决方案。
    【解决方案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'}
        }]
    });
    

    附:确切的代码可能不起作用,但概念是相同的。希望这会对你有所帮助。有关更多信息,请点击参考资料中的链接 参考:Sequelize Associations

    【讨论】:

    • 工作,几乎完美!需要进行一些更改以适应(主要是方法签名调整),但效果非常好,并且连接正确
    猜你喜欢
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 2022-12-15
    • 2017-05-18
    • 2016-12-03
    • 1970-01-01
    相关资源
    最近更新 更多