【问题标题】:Find all rows around 10km radius with GORM and PostgreSQL使用 GORM 和 PostgreSQL 查找半径 10 公里左右的所有行
【发布时间】:2021-05-05 08:03:30
【问题描述】:

我想列出StartAddress周围10公里半径内的races(加入表Address

我的模型是这样写的:

    type (
        // Race model
        Race struct {
            Base // ID, CreatedAt, UpdatedAt, DeletedAt
            Title          string            `json:"title" gorm:"title;"`
            StartAddress   Address           `json:"startaddress" gorm:"foreignKey:StartAddressID"`
            StartAddressID string            `json:"start_address_id" gorm:"type:char(36);start_address_id;"`
            EndAddress     Address           `json:"endaddress" gorm:"foreignKey:EndAddressID"`
            EndAddressID   string            `json:"end_address_id" gorm:"type:char(36);end_address_id;"`
            StartDate      time.Time         `json:"start_date" gorm:"start_date;"`
            EndDate        time.Time         `json:"end_date" gorm:"end_date;"`
        }

        Address struct {
            Base // ID, CreatedAt, UpdatedAt, DeletedAt
            Street  string  `json:"street" gorm:"street;"`
            Zipcode string  `json:"zipcode" gorm:"zipcode;"`
            City    string  `json:"city" gorm:"city;"`
            Lat     float64 `json:"lat" gorm:"lat;"`
            Lng     float64 `json:"lng" gorm:"lng;"`
        }
    )

要查询我的数据库,我使用GORM v2

我不知道如何通过 GORM 编写使用 PostgreSQL 的 cubeearthdistance 扩展的查询。

我已经添加了扩展:

CREATE EXTENSION cube;

CREATE EXTENSION earthdistance;

类似,但使用 GORM 语法,按距离排序:

SELECT * FROM races
INNER JOIN addresses ON addresses.id = races.start_address_id
AND earth_box(ll_to_earth(48.8589507,2.2770205), 5000) @> ll_to_earth(addresses.lat, addresses.lng)
ORDER BY races.status DESC
LIMIT 100

【问题讨论】:

  • 您好。只是出于好奇,您为什么选择 earthdistance 而不是 postgis 来处理空间数据?欢呼
  • @JimJones 谢谢你的提问,我选择了我认为更合适的“earthdistance”汽车,它得到了 Postgres 的官方支持。我愿意使用 PostGIS 或任何扩展。
  • 据我所知,PostGIS 是迄今为止处理空间数据的最合适的扩展。在这个答案中,您可以找到一个计算距离的示例:stackoverflow.com/a/51889638/2275388

标签: sql postgresql go go-gorm


【解决方案1】:

你在那里的查询可以在 Gorm 中这样完成:

var res []Race

db.Model(&Race{}).
    Joins("StartAddress").
    Where("earth_box(ll_to_earth(?,?), ?) @> ll_to_earth(addresses.lat, addresses.lng)", ptLat, ptLng, dist).
    Order("races.status DESC").
    Limit(100).
    Find(&res)

要按距离获取订单,您需要将 Order(...). 替换为:

    Clauses(clause.OrderBy{
        Expression: clause.Expr{
            SQL: "earth_distance(ll_to_earth(?,?), ll_to_earth(addresses.lat, addresses.lng)) ASC", 
            Vars: []interface{}{ptLat, ptLng}, 
            WithoutParentheses: true,
        },
    }).

【讨论】:

  • 感谢您的回答,两种选择我都有这个错误:ERROR: syntax error at end of inputSELECT [...] FROM "races" LEFT JOIN "addresses" "StartAddress" ON "races"."start_address_id" = "StartAddress"."id" WHERE earth_box(ll_to_earth(53.3781516,-9.338521), '5000') @> ll_to_earth(addresses.lat, addresses.lng AND "races"."deleted_at" IS NULL ORDER BY races.status DESC
  • 我的代码中有错字,看到了吗?第二个 ll_to_earth 缺少一个括号。
  • 非常感谢您的回复。如果出现错误,我只需将出现的“addresses.lat”和“addresses.lng”替换为“lat”和“lng”。
猜你喜欢
  • 2015-10-18
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
  • 2020-05-03
  • 2019-11-29
  • 1970-01-01
  • 2022-06-25
相关资源
最近更新 更多