8000 Virtual entity custom filter query · Issue #5971 · mikro-orm/mikro-orm · GitHub
[go: up one dir, main page]

Skip to content

Virtual entity custom filter query  #5971

@khaled-hamam

Description

@khaled-hamam

Is your feature request related to a problem? Please describe.
The way EntityManager.find (and other methods) work, is that they infer the properties existing in the entity passed as the first value, and use its properties as a filter query in the second parameter.

This is a problem with virtual entities where some filters are needed that only appear in the query but don't end up in the entity.

For example something like:

@Entity({
  expression: (em, where) => {
    return em.aggregate(Book, [
      { $match: { genre: where.genre } },
      { $group: { _id: "$userId" } },
      { $lookup: { from: "user", localField: "_id", foreignField: "_id", as: "publisher" } },
      { $unwind: "$publisher" },
      { $replaceRoot: { newRoot: "$publisher" } }
    ]);
  }
})
export class Publisher {
  @Property()
  public _id: ObjectId;
}

In this example I'm trying to get users who have books using the virtual entity, and I need to query based on the genre field from the Book entity, but the genre isn't in the Publisher virtual entity. This will cause the following type error on genre:

const publishers = await em.find(Publisher, { genre: "non-fiction" });
^^^-> Object literal may only specify known properties, and 'genre' does not exist in type 'RegExp | ObjectId | ObjectQuery<Publisher> | NonNullable<EntityProps<Publisher> & OperatorMap<Publisher>> | FilterQuery<...>[]'.ts(2353)

Describe the solution you'd like
I think one way to do it is to be able to override the FilterQuery<T> type using a symbol like you're already doing with OptionalProps and others.

So the usage will be:

@Entity
export class VirtualEntity {
  public readonly [FilterQueryOverride]?: { genre: string };

  // ...
}

Now FilterQuery<VirtualEntity> should result in { genre: string }.

Describe alternatives you've considered
I don't have any other proper solutions for this issue. Please let me know if I'm missing something that can resolve this.

Additional context
I know we can override this by just casting the object as FilterQuery<T> or even any but I'm trying to suggest a solution that keeps the type safety and proper auto completions working.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0