Drizzle | PostgreSQL 中的点数据类型
This guide assumes familiarity with:
- 开始使用 PostgreSQL
- 点数据类型
- 选择语句中的过滤
- sql 操作符
PostgreSQL 具有一种特殊的数据类型用于存储几何数据,称为 point
。它用于表示二维空间中的一个点。点数据类型以一对 (x, y)
坐标表示。
点数据类型期待先接收经度,然后是纬度。
import { sql } from 'drizzle-orm';
const db = drizzle(...);
await db.execute(
sql`select point(-90.9, 18.7)`,
);
[
{
point: '(-90.9,18.7)'
}
]
以下是如何在 Drizzle 中创建一个具有 point
数据类型的表:
import { pgTable, point, serial, text } from 'drizzle-orm/pg-core';
export const stores = pgTable('stores', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
location: point('location', { mode: 'xy' }).notNull(),
});
以下是如何在 Drizzle 中插入点数据到表中:
// mode: 'xy'
await db.insert(stores).values({
name: 'Test',
location: { x: -90.9, y: 18.7 },
});
// mode: 'tuple'
await db.insert(stores).values({
name: 'Test',
location: [-90.9, 18.7],
});
// sql 原生
await db.insert(stores).values({
name: 'Test',
location: sql`point(-90.9, 18.7)`,
});
要计算对象之间的距离,可以使用 <->
操作符。以下是如何在 Drizzle 中根据坐标查询最近位置:
import { getTableColumns, sql } from 'drizzle-orm';
import { stores } from './schema';
const point = {
x: -73.935_242,
y: 40.730_61,
};
const sqlDistance = sql`location <-> point(${point.x}, ${point.y})`;
await db
.select({
...getTableColumns(stores),
distance: sql`round((${sqlDistance})::numeric, 2)`,
})
.from(stores)
.orderBy(sqlDistance)
.limit(1);
select *, round((location <-> point(-73.935242, 40.73061))::numeric, 2)
from stores order by location <-> point(-73.935242, 40.73061)
limit 1;
要过滤行以仅包括 point
类型的 location
在由两个对角点定义的指定矩形边界内的行,可以使用 <@
操作符。该操作符检查第一个对象是否被包含在第二个对象内或在其上:
const point = {
x1: -88,
x2: -73,
y1: 40,
y2: 43,
};
await db
.select()
.from(stores)
.where(
sql`${stores.location} <@ box(point(${point.x1}, ${point.y1}), point(${point.x2}, ${point.y2}))`
);
select * from stores where location <@ box(point(-88, 40), point(-73, 43));