javascript - 在急切加载期间,错误 : Tried to select attributes using Sequelize. 强制转换或 Sequelize.fn 未指定结果别名

标签 javascript node.js sequelize.js

数据:一个办公室有许多OfficeLocations,每个办公室都有许多评级。我需要编写一个查询,仅获取至少有一个 RatingOffices。我的查询:

let condition = {
    include: [{
        model: OfficeLocation.unscoped(),
        attributes: [
            '"Office"."id" as "Office.id"',
            '"OfficeLocations"."id" AS "OfficeLocation.id"'
        ],
        include: [
            {
                model: Rating.unscoped(),
                attributes: [
                    '*',
                    sequelize.fn('COUNT', sequelize.col('"OfficeLocations->Ratings"."id"'))
                ]
            }
        ],
        group: '"Office.id", "OfficeLocation.id"',
        having: sequelize.where(
            sequelize.fn('COUNT', sequelize.col('"OfficeLocations->Ratings"."id"')),
            '>',
            0
        )
    }]
}

Office.findAll(condition).then(data => {
    res.send(data);
}).catch(e => {
    console.log(e);
});

但是我在控制台中出现错误:

Error: Tried to select attributes using Sequelize.cast or Sequelize.fn without specifying an alias for the result, during eager loading. This means the attribute will not be added to the returned instance
at include.attributes.map.attr (/Users/.../node_modules/sequelize/lib/dialects/abstract/query-generator.js:1307:17)
at Array.map (<anonymous>)
at Object.generateInclude (/Users/.../node_modules/sequelize/lib/dialects/abstract/query-generator.js:1287:52)
at Object.generateInclude (/Users/.../node_modules/sequelize/lib/dialects/abstract/query-generator.js:1355:39)

我也尝试过

where: sequelize.literal('COUNT(DISTINCT(`OfficeLocations`.`Ratings`.`id`)) > 0'),

而不是 attribute/group/having,但它也不起作用。

谢谢。

更新

这个 SQL 查询可以满足我的需要:

sequelize.query(`
    SELECT
    "Office"."id" as "Office.id",
    "Office"."name",
    "Office"."website",
    "OfficeLocations"."id" AS "OfficeLocations.id",
    COUNT("OfficeLocations->Ratings"."id") as "RatingsCount"

    FROM "Companies" AS "Office"
    LEFT OUTER JOIN ( "OfficeLocations" AS "OfficeLocations"
        INNER JOIN "Ratings" AS "OfficeLocations->Ratings"
        ON "OfficeLocations"."id" = "OfficeLocations->Ratings"."OfficeLocationId"
    )
    ON "Office"."id" = "OfficeLocations"."OfficeId"

    GROUP BY "Office.id", "OfficeLocations.id"
    HAVING COUNT("OfficeLocations->Ratings"."id") > 0
`)

除非我想获取所有数据。

最佳答案

请参阅Model.findAll options 参数的语法。

  1. grouphavingoptions 对象的属性。
  2. 对于所选列/表达式的别名(属性选项),请使用数组:[expr, alias]
  3. 您可以传递 attributes.include 和/或 attributes.exclude 数组。
  4. 您可以传递 include[].attributes 选项以引用所包含模型的属性。
  5. 您还可以使用 include[].required 选项在 INNER JOIN 和 OUTER JOIN 之间进行选择。

您的案例:

let options = {
        include: [
            {
                model: OfficeLocation,
                required: false, //false for OUTER JOIN, but I think that you can use INNER JOIN
                attributes: [
                    "id", //this is OfficeLocation.id, see 4th item above. 
                    [Sequelize.fn("COUNT", Sequelize.col('`OfficeLocations->Ratings`.`id`')), "RatingsCount"]
                ],
                include: [
                    {
                        model: UserRating,
                        attributes: [],
                        required: true
                    }
                ]
            }
        ],
        group: [
            `Office.id`,
            `OfficeLocations.id`
        ],
        having: Sequelize.where(Sequelize.fn("COUNT", Sequelize.col('`OfficeLocations->Ratings`.`id`')), ">", 0)
    };

请注意,Sequelize 生成的别名可能会发生变化,因此您应该更新 Sequelize.col

关于javascript - 在急切加载期间,错误 : Tried to select attributes using Sequelize. 强制转换或 Sequelize.fn 未指定结果别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53566289/

相关文章:

node.js - 如何在 node.js 中跟踪(更改)日志文件

javascript - Express POST - 返回的 JSON 被 JQuery 视为无效

node.js - 无法按日期/时间在 Waterline 中找到记录

node.js - 使用条件对内连接进行 Sequelize

sequelize.js - 更新到 Sequelize-Typescript 5 导致异常 "column createdAt does not exist"

javascript - 使用sequelize ownTo 和 hasOne 会导致超出最大调用堆栈大小

javascript 附加值 jquery

javascript - 如何使用 Meteor js 在 Stripe 成功后重定向到成功页面

javascript - 保持函数在条件下执行

javascript - 仅从具有多个属性的 HTML 选择中获取新添加和删除的选项?