【问题标题】:Mikro-orm order by ST_Distance_Sphere using MySQL driverST_Distance_Sphere 使用 MySQL 驱动程序的 Mikro-orm 命令
【发布时间】:2020-07-18 20:24:49
【问题描述】:

对于 MySQL,我正在尝试使用 QueryBuilderST_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 错误:

尝试通过不存在的属性 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]

【问题讨论】:

    标签: mikro-orm


    【解决方案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 的方法应该是开箱即用的

    【讨论】:

    • 如果你愿意,我可以在 GitHub repo 上打开一个问题。
    • 是的,否则我不能保证我不会忘记:]
    猜你喜欢
    • 1970-01-01
    • 2021-08-30
    • 2022-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2012-07-20
    • 2022-01-09
    相关资源
    最近更新 更多