【问题标题】:How to use an operator in where clause with an optional include?如何在带有可选包含的 where 子句中使用运算符?
【发布时间】:2017-11-24 10:53:21
【问题描述】:

我有以下型号:

AuthorModel.hasMany(BookModel);
BookModel.belongsTo(AuthorModel);

有些作者没有书。

我想选择一个作者,他的一本书的名字或标题与搜索字符串匹配。

我可以通过以下语句实现这一点,但仅适用于在 BookModel 中有书籍的作者

       Author.findOne({
         include: [{
            model: Book,
            where: {
              [Op.or]: [
                  {'$author.name$': 'search string'},
                  { title: 'search string'}
                 ]
               },
             }]
           })

这或多或少给了我以下mysql 查询:

SELECT 
    `author`.`name`,
    `book`.`title`
FROM `author` INNER JOIN `book` 
     ON `author`.`id` = `book`.`authorId`
     AND ( `author`.`name` = 'search string' OR `book`.`title` = 'search string');

这里的问题是,如果作者没有书,那么结果是空的。即使有符合搜索条件的作者。

我尝试将包含设置为required: false,它给出了left outer join。在这种情况下,我会得到一些不匹配的结果。 where 子句被省略。

如何更改我的sequelize 查询,或者正确的mysql 查询是什么?

【问题讨论】:

    标签: mysql sequelize.js


    【解决方案1】:

    MySql 查询应该类似于

    SELECT 
        `author`.`name`,
        `book`.`title`
    FROM `author` LEFT JOIN `book` 
         ON `author`.`id` = `book`.`authorId`
    WHERE ( `author`.`name` = 'search string' OR `book`.`title` = 'search string')
    

    注意这里的过滤条件是在WHERE而不是JOIN ... ON子句的一部分

    根据Top level where with eagerly loaded models 的示例,您的 squizzle 查询可能类似于

    Author.findOne({
        where: {
              [Op.or]: [
                  {'$author.name$': 'search string'},
                  { '$Book.title$': 'search string'}
                 ]
               },
        include: [{
            model: Book,           
            required: false
           }]})
    

    【讨论】:

    • 谢谢,但这并不能解决我的问题。如果作者没有书,你的 MySQL 会给出 0 个结果,即使搜索字符串会匹配作者的名字。 sequelize 声明在几个方面也是错误的,对我来说行不通。 where 子句必须在 include 中,否则无法访问其中的Book
    • @henk,您是否尝试过针对一些真实数据的 SQL 查询? AFAICS here 似乎工作正常,除非我误解了您的要求。至于 sequelize 查询,语法在某些细节上可能有问题,因为我没有尝试过,但是如果您查看我在答案中引用的 link,您会发现您可以将 where 子句放在外面include 并且仍然使用类似于我的查询的语法引用连接表。
    • 再检查一遍,其实你的mysql语句是对的,谢谢。问题在于.findOne 它给出了一种奇怪的MySQL 语句,带有select ... from (select ... as author .. where ...) left outer join ...。出于这个原因,include 之外的where 子句将放在括号内,而books 没有在那里定义。现在的解决方案是.findAll。在检查您的 MySQL 语句时,这也误导了我。
    • @henk,我的回答最终有帮助还是没有帮助?
    • 问题已经解决了,所以我会说是的:D。只是在想我是否应该保持打开状态,以防有人可以解释使用.findOne 背后的问题以及如何正确使用它来达到我的目的。但也许这是另一个问题
    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多