SequelizeJS: Recursive include same model

夙愿已清 提交于 2019-12-11 04:53:57

问题


I want to fetch data from a Postgres database recursively including all associated models using SequelizeJS.

GeoLocations table

id | isoCode | name | parentId | type | updatedAt | deletedAt

parentId holds the id of the parent GeoLocation.

Model Associations

GeoLocation.belongsTo(GeoLocation, {
    foreignKey: 'parentId',
    as: 'GeoLocation'
});

Data explanation and example

GeoLocation types and their relations: city -> subdivision -> country -> continent

id: 552, name: Brooklyn, type: city, parentId: 551
id: 551, name: New York, type: subdivision, parentId: 28
id: 28, name: United States, type: country, parentId: 27
id: 27, name: North America, type: continent, parentId: NULL

Now, when querying a city, I want all relations to be included as long as parentId is set.

GeoLocation.findOne({
    where: {
        id: 552
    },
    include: [
        {
            model: GeoLocation,
            as: 'GeoLocation',
            include: [
                {
                    model: GeoLocation,
                    as: 'GeoLocation',
                    include: [
                        {
                            model: GeoLocation,
                            as: 'GeoLocation',
                        }
                    ],
                }
            ],
        }
    ],
});

Response in JSON

{  
   "GeoLocation":{  
      "id":552,
      "type":"city",
      "name":"Brooklyn",
      "GeoLocation":{  
         "id":551,
         "type":"subdivision",
         "name":"New York",
         "GeoLocation":{  
            "id":28,
            "type":"country",
            "name":"United States",
            "GeoLocation":{  
               "id":27,
               "type":"continent",
               "name":"North America"
            }
         }
      }
   }
}

The solution above works, but I have the strong feeling, that there are better ways to do this, without having to include the model multiple times. I can't find anything related in the docs. Am I missing something?


回答1:


I already moved on a different solution. I am not using sequelize native pseudo language to achieve this. Because apparently, recursive includes feature is not possible with sequelize.

Here is the recursive model I use :

I want this recursive info, which organisation is related to which, no matter how I get this info, I'll process it later to get the info into shape (tree, flat list, ... whatever)

I use a sequelize RAW query involving recursive SQL:

exports.getArborescenceByLienId = function (relationType, id) {
    const query = 'With cte as (\n' +
        '    select  id_organisationSource, \n' +
        '            relationType,\n' +
        '            id_organisationTarget\n' +
        '    from    (\n' +
        '                    select * from relation where relationType= :relationType\n'     +
        '                ) relations_sorted,\n' +
        '            (\n' +
        '                  select @pv := :orgId\n' +
        '                ) initialisation\n' +
        '    where   find_in_set(id_organisationSource, @pv)\n' +
        '    and     length(@pv := concat(@pv, \',\', id_organisationTarget))\n' +
        ')\n' +
        'select source.id as `idSource`, cte.relationType, target.id as `idTarget`\n' +
        'from cte \n' +
        'left outer join organisation source on cte.id_organisationSource = source.id\n' +
        'left outer join organisation target on cte.id_organisationTarget = target.id;';
    return models.sequelize.query(
        query,
        {
            type: models.sequelize.QueryTypes.SELECT,
            replacements: { orgId: id, relationType: relationType}
        }
    );
};

Imagine I have an object model like this:

(Assuming each relation here have same type : say isManaging) Result of query with ID = 1 would be :

Result of query with ID = 2 would be :

I then transform this flat list to a Tree, and VOILA :)

Let me know if your interested in this Flat list to tree transforming algorithm.

Hope this help. Cheers !



来源:https://stackoverflow.com/questions/44456470/sequelizejs-recursive-include-same-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!