sequelize association:从多个到多个关联查询最后一个created_At关联

时间:2014-11-06 17:37:38

标签: node.js sequelize.js

使用此架构:

var user = sequelize.define('user', {
    username: Sequelize.STRING,
    email: Sequelize.STRING,
    password: Sequelize.STRING
}, {
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at'
});

var status = sequelize.define('status', {
  status: Sequelize.STRING,
  description: Sequelize.TEXT
}, {
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at'
});

var users_statuses = sequelize.define('users_statuses', {
    user_id: Sequelize.INTEGER(11),
    status_id: Sequelize.INTEGER(11),
}, {
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at'
});

user.hasMany(status, { foreignKey: 'user_id', through: models.users_statuses });
status.hasMany(user, { foreignKey: 'status_id', through: models.users_statuses });

因此每个用户都有许多状态(以跟踪所有选定的状态)。 使用find with include或getter user.getStatuses()我可以获得实际用户的所有状态,但我无法确定如何获取最后/当前关联状态(基于users_statuses表的created_at列) /模型)

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

1个数据库查询的快速修复。使用

user.find({
    where: {user_id : id },
    include: [{
        model: status,
        attributes: ['status']
    }],
    order: [ [ status, 'createdAt', 'DESC'] ]
}).then(function(user) {
    var latestStatus = user.status[0];
}).catch(function(err) {
    console.log(err);
});

但这会浪费时间来获得您不需要的所有状态。如果您有很多状态,那么Sequelize可能会浪费更多时间来截断结果,而不是进行其他查询。

更好的方法是在user_status表中搜索最新的createdAt状态,并在status表上执行另一个查询:

user_status.find({
    where: {user_id: yourid}
    order: [ 'createdAt', 'DESC']
}).then(function(user_status) {
    var latest_status_id = user_status.status_id;
    return status.find(where:{status_id: latest_status_id});
}).then..... catch....;

当然,最好的方法。但是,这将要求您将表与其交叉表相关联,而不是让sequelize使用“通过”来执行此操作。

如果您的user_status是一个强大的实体,并且它具有以下关系:

user_status.belongsTo(status, {foreignKey: status_id});

然后你可以这样做:

user_status.find({
    where: {user_id: id},
    include: [{
        model: status
    }],
    order: [ [ 'createdAt', 'DESC' ] ]
}).then....

基本思想是“包含”只能用于强实体。当您使用hasMany... through...时,交叉表是一个弱实体,不能具有“包含”。

答案 1 :(得分:1)

您可以使用:



.find({ limit: 1, order: 'updatedAt DESC' })