【问题标题】:Sails Waterline SQL join in populateSails Waterline SQL 加入填充
【发布时间】:2014-07-14 19:08:26
【问题描述】:

Waterline 是否支持执行 SQL 连接(query() 除外)?我已经在我的模型中设置了关联,但生成的实际 SQL 查询是循环选择语句。当前是否仅支持“n+1 选择”?我是否在某处缺少配置选项?

这是一个 1->Many populate 的示例,它循环选择语句: (sails/waterline/sails-mysql v0.10.0-rc8)

/**
* City.js
*/
module.exports = {
"adapter": "someMysqlServer",
"tableName": "city",
autoCreatedAt: false,
autoUpdatedAt: false,
schema: true,
attributes: {
    "id": {
        "type": "integer",
        "primaryKey": true,
        "autoIncrement": true,
        "columnName": "ID"
    },
    "Name": {
        "type": "string",
        "maxLength": 35
    },
    "District": {
        "type": "string",
        "maxLength": 20
    },
    "Population": {
        "type": "integer"
    },
    "CountryCode": {
        //a city has one country
        "model": "Country"
    }
}};




/**
* Country.js
*/

module.exports = {
  "adapter": "someMysqlServer",
  "tableName": "country",
  autoCreatedAt: false,
  autoUpdatedAt: false,
  schema: true,
  attributes: {
      "id": {
          "type": "string",
          "required": true,
          columnName: "Code",
          "primaryKey": true,
          "maxLength": 3
      },
      "Name": {
          "type": "string",
          "maxLength": 52
      },
      Continent: "string",
      "Region": {
          "type": "string",
          "maxLength": 26
      },
      SurfaceArea: "float",
      IndepYear: "integer",
      Population: "integer",
      LifeExpectancy: "float",
      GNP: "float",
      GNPOld: "float",
      LocalName: "string",
      GovernmentForm: "string",
      HeadOfState: "string",
      Capital: "integer",
      Code2: "string",
      Cities: {
          //country has many cities
          "collection": "City",
          "via": "CountryCode"
      }
  }
};

然后,当我导航到 http://localhost:1337/country?populate=[Cities] 时,我的日志显示执行了以下 sql:

SELECT `country`.`Name`, `country`.`Continent`, `country`.`Region`, `country`.`SurfaceArea`, `country`.`IndepYear`, `country`.`Population`, `country`.`LifeExpectancy`, `country`.`GNP`, `country`.`GNPOld`, `country`.`LocalName`, `country`.`GovernmentForm`, `country`.`HeadOfState`, `country`.`Capital`, `country`.`Code2`,`country`.`Code` FROM `country` LIMIT 30 OFFSET 0
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ABW' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AFG' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AGO' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AIA' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ALB' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AND' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ANT' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ARE' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ARG' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ARM' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ASM' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ATA' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ATF' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='ATG' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AUS' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AUT' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='AZE' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BDI' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BEL' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BEN' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BFA' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BGD' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BGR' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BHR' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BHS' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BIH' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BLR' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BLZ' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BMU' LIMIT 30
SELECT `city`.`Name`, `city`.`CountryCode`, `city`.`District`, `city`.`Population`, `city`.`ID` FROM `city` WHERE `city`.`CountryCode`='BOL' LIMIT 30

【问题讨论】:

  • 我遇到了同样的问题。测试我是否使用 ?populate=[model] url 我得到相同的行为。如果我明确调用 Model.find().populate('OtherModel') 我会得到一个稍微优化的版本(使用 IN)但仍然没有加入。

标签: node.js sails.js waterline


【解决方案1】:

测试版中的.populate() 实现被刻意简化以支持尽可能广泛的适配器集。在最终的 v0.10 版本中,受支持的“核心”SQL 适配器(sails-mysql 和sails-postgresql)将执行实际连接。

【讨论】:

  • @sgress454这有什么更新吗?我刚刚安装了sails 0.10.2 和sails-mysql 0.10.4,mysql 日志显示以下输出:(SELECT * FROM city AS city WHERE CountryCode = "ABW" ORDER BY city.id ASC LIMIT 30) UNION (SELECT * FROM city AS city WHERE CountryCode = "AFG" ORDER BY city.id ASC LIMIT 30) UNION (SELECT * FROM city AS city WHERE CountryCode = "AGO" ORDER BY city.id ASC LIMIT 30) (...)
  • 这是因为您正在访问默认限制为 30 条记录的蓝图路由。在这种情况下,您不能进行简单的连接,因为查询将只返回 30 行,而您真正想要的是最多 900 行(30 个国家/地区,每个国家/地区有 30 个城市)。因此,UNION 仍然比为每个国家/地区单独查询要好得多。如果您可以将其归结为单个查询,我们将非常有兴趣看到它!有关该问题的更多信息,请参阅this article
猜你喜欢
  • 2016-04-18
  • 1970-01-01
  • 2014-05-12
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多