ST_Distance_Sphere 使用 MySQL 驱动程序的 Mikro-orm 命令
Mikro-orm order by ST_Distance_Sphere using MySQL driver
使用 MySQL,我尝试使用 QueryBuilder
在 ST_Distance_Sphere
之前订购。
我有一个实体:
import { Entity, PrimaryKey, Property } from "mikro-orm";
@Entity({ tableName: "studio" })
export default class StudioEntity {
@PrimaryKey()
public id!: number;
@Property()
public name!: string;
@Property({ columnType: "point srid 4326" })
public geometry!: object;
}
我正在尝试:
export default class StudioStore {
private studioRepository: EntityRepository<StudioEntity>;
public constructor(ormClient: OrmClient) {
this.studioRepository = ormClient.em.getRepository(StudioEntity);
}
public async findPage(first: number): Promise<StudioEntity[]> {
const query = this.studioRepository.createQueryBuilder().select("*");
query.addSelect(
"ST_Distance_Sphere(`e0`.`geometry`, ST_GeomFromText('POINT(28.612849 77.229883)', 4326)) as distance",
);
query.orderBy({ distance: "ASC" });
return query.limit(first).getResult();
}
}
但是我收到一个 ORM 错误:
Trying to query by not existing property StudioEntity.distance
所以,我尝试添加一个 属性 到实体:
@Property({ persist: false })
public distance?: number;
但现在我收到 MySQL 错误:
Unknown column 'e0.distance' in 'order clause'
这是生成的 SQL 查询:
[query] select `e0`.*, ST_Distance_Sphere(`e0`.`geometry`, ST_GeomFromText('POINT(28.612849 77.229883)', 4326)) as distance from `studio` as `e0` order by `e0`.`distance` asc limit 5 [took 4 ms]
您需要回退到 knex,因为 QB 目前仅支持定义的 属性 字段排序依据。您还需要像之前那样定义虚拟 distance
属性,以便可以将值映射到实体。
https://mikro-orm.io/docs/query-builder/#using-knexjs
const query = this.studioRepository.createQueryBuilder().select("*");
query.addSelect("ST_Distance_Sphere(`e0`.`geometry`, ST_GeomFromText('POINT(28.612849 77.229883)', 4326)) as distance");
query.limit(first);
const knex = query.getKnexQuery();
knex.orderBy('distance', 'asc');
const res = await this.em.getConnection().execute(knex);
const entities = res.map(a => this.em.map(StudioEntity, a));
我必须说不是很好,完全忘记了可以按计算字段排序。将尝试在 v4 中解决这个问题。我认为它甚至可以作为你的第二种方法,因为 QB 可以简单地检查 属性 是否是虚拟的(有 persist: false
),然后它不会给它加上前缀。
编辑:从 3.6.6 开始,persist: false
的方法应该开箱即用
使用 MySQL,我尝试使用 QueryBuilder
在 ST_Distance_Sphere
之前订购。
我有一个实体:
import { Entity, PrimaryKey, Property } from "mikro-orm";
@Entity({ tableName: "studio" })
export default class StudioEntity {
@PrimaryKey()
public id!: number;
@Property()
public name!: string;
@Property({ columnType: "point srid 4326" })
public geometry!: object;
}
我正在尝试:
export default class StudioStore {
private studioRepository: EntityRepository<StudioEntity>;
public constructor(ormClient: OrmClient) {
this.studioRepository = ormClient.em.getRepository(StudioEntity);
}
public async findPage(first: number): Promise<StudioEntity[]> {
const query = this.studioRepository.createQueryBuilder().select("*");
query.addSelect(
"ST_Distance_Sphere(`e0`.`geometry`, ST_GeomFromText('POINT(28.612849 77.229883)', 4326)) as distance",
);
query.orderBy({ distance: "ASC" });
return query.limit(first).getResult();
}
}
但是我收到一个 ORM 错误:
Trying to query by not existing property StudioEntity.distance
所以,我尝试添加一个 属性 到实体:
@Property({ persist: false })
public distance?: number;
但现在我收到 MySQL 错误:
Unknown column 'e0.distance' in 'order clause'
这是生成的 SQL 查询:
[query] select `e0`.*, ST_Distance_Sphere(`e0`.`geometry`, ST_GeomFromText('POINT(28.612849 77.229883)', 4326)) as distance from `studio` as `e0` order by `e0`.`distance` asc limit 5 [took 4 ms]
您需要回退到 knex,因为 QB 目前仅支持定义的 属性 字段排序依据。您还需要像之前那样定义虚拟 distance
属性,以便可以将值映射到实体。
https://mikro-orm.io/docs/query-builder/#using-knexjs
const query = this.studioRepository.createQueryBuilder().select("*");
query.addSelect("ST_Distance_Sphere(`e0`.`geometry`, ST_GeomFromText('POINT(28.612849 77.229883)', 4326)) as distance");
query.limit(first);
const knex = query.getKnexQuery();
knex.orderBy('distance', 'asc');
const res = await this.em.getConnection().execute(knex);
const entities = res.map(a => this.em.map(StudioEntity, a));
我必须说不是很好,完全忘记了可以按计算字段排序。将尝试在 v4 中解决这个问题。我认为它甚至可以作为你的第二种方法,因为 QB 可以简单地检查 属性 是否是虚拟的(有 persist: false
),然后它不会给它加上前缀。
编辑:从 3.6.6 开始,persist: false
的方法应该开箱即用