ST_Distance_Sphere使用MySQL驱动程序对Mikro-orm进行排序

时间:2020-04-06 18:32:56

标签: mikro-orm

对于MySQL,我尝试使用ST_Distance_SphereQueryBuilder进行订购。

我有一个实体:

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错误:

尝试通过不存在的属性StudioEntity.distance查询

因此,我尝试向实体添加属性:

    @Property({ persist: false })
    public distance?: number;

但是现在我收到一个MySQL错误:

“订单子句”中的未知列“ e0.distance”

这是生成的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]

1 个答案:

答案 0 :(得分:1)

您将需要回退到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的方法应该可以立即使用