Sequelize where has NOT

29

我有一个 Sequelize 模型,名为 Article,其中文章相互关联。有些文章是其他文章的翻译副本。关系设置如下:

var Article = sequelize.define('Article', {
    type                : DataTypes.ENUM('source', 'translated'),
    sourceArticleId     : DataTypes.INTEGER
});

db.Article.hasMany(db.Article, {
    foreignKey: 'sourceArticleId',
    as        : 'TranslatedArticles'
});

因此,具有type = 'source'的文章可以有多个translatedArticles,其中type = 'translated'

现在,我想查询所有没有翻译的source文章。

根据Sequelize项目GitHub上的一篇问题,可以像这样完成:

Article.findOne({
    where: Sequelize.literal('translatedArticles.sourceArticleId IS NULL'),
    include: [
        {
            model: Article,
            as   : 'TranslatedArticles'
        }
    ]
});

然而,当我运行这段代码时,出现了以下错误:

SequelizeDatabaseError: ER_BAD_FIELD_ERROR: Unknown column 'translatedArticles.sourceArticleId' in 'where clause'

我还尝试了各种命名方式,包括 TranslatedArticles.sourceArticleId, articles.sourceArticleId, 和 Articles.sourceArticleId

我错过了什么吗?

请注意,我通过使用文字NOT EXISTS查询来暂时解决了这个问题,类似于:

Article.findOne({
    where: Sequelize.literal('NOT EXISTS (SELECT id FROM Articles WHERE Article.id = Articles.sourceArticleId LIMIT 1)')
});

你使用哪个版本? - yanana
@yanana 版本 3.3.1 - Tom
你能打开SQL日志,看看Sequelize查询构建器正在尝试查询什么吗? - Steven Lu
@StevenLu 这个日志在 https://gist.github.com/tommedema/5f5ad310a3f31b1dccaa - Tom
3个回答

3

我不知道你们后端使用的是哪种数据库技术,但我猜测它是大小写敏感的。我认为它没有找到字段是因为你需要将"translatedArticles"中的t大写。下面的代码应该可以解决这个问题:

Article.findOne({
    where: Sequelize.literal('TranslatedArticles.sourceArticleId IS NULL'),
    include: [
        {
            model: Article,
            as   : 'TranslatedArticles'
        }
    ]
});

2

也许我已经找到了解决方案,使用 subQuery: false,这个选项在文档中没有提到。

Article.findOne({
    subQuery: false,
    where: Sequelize.literal('translatedArticles.sourceArticleId IS NULL'),
    include: [
        {
            model: Article,
            as   : 'TranslatedArticles'
        }
    ]
});

0

我只是根据个人理解来回答,但我认为可以这样实现:

Article.findOne({
    include: [
        {
            model: Article,
            as   : 'TranslatedArticles',
            attributes: [[models.sequelize.fn('COUNT', 'sourceArticleId'), 'translationCount']]
            having: {
                translationCount: 0
            },
        }
    ]
});

那个修订版本可能更接近答案吗? - swifty
这会返回 SequelizeDatabaseError: ER_BAD_FIELD_ERROR: 'where clause' 中未知的列 'TranslatedArticles.translationCount' 并且生成了 SQL https://gist.github.com/tommedema/66e8ae5b715b31c337a9 - Tom
业余错误!由于这是一个计数,我应该使用HAVING而不是WHERE - swifty
当它运行时,它会返回文章,无论是否有其他文章的sourceArticleId等于返回的文章。因此,这不是期望的行为。我需要返回没有翻译文章的源文章,翻译文章是指源文章ID等于源文章的文章。生成的SQL是https://gist.github.com/tommedema/fa400097df063ddf5d75 - Tom
当然,除非它是左连接,否则可以通过包含模型中的 required:false 选项来完成。 - swifty
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接