Support filtering interface/union types on _typename#1169
Support filtering interface/union types on _typename#1169marcdaniels-toast wants to merge 1 commit into
Conversation
I think this known limitation is a problem. I think we either need to get I think there's a solution, though--and it's one that should support more optimal queries to boot: let's leverage the That said, there's a situation that's tricky to solve. Imagine this: And imagine a query comes in like this: distributionChannels(filter: {
_typename: {equalToAnyOf: ["PhysicalStore", "BrokerWholesale"]}
}) {
# ...
}This query needs to hit both the Now that I've thought of using Also, I just realized something while writing that up--a client might try this: distributionChannels(filter: {
_typename: {equalToAnyOf: ["Wholesale"]}
}) {
# ...
}A client could try that expecting it to return all documents that are subtypes of
I want to hear what you favor but to share my two cents: I like the 2nd option a lot for the type safety it provides, but I think I ultimately lean towards the first option, for a few reasons:
Thoughts @marcdaniels-toast? |
|
Thanks for pushing back on the limitation. It did seem a bit awkward at the time but I didn't know we had such a clean solution as As for filtering by abstract types, what about query-time expansion? When the filter interpreter sees a |
Adds a `_typename` field to all abstract type filter inputs, allowing callers to filter results by the concrete type of each document. This supports use cases like filtering a `retailers` query to only return `OnlineStore` or `PhysicalStore` results. The filter maps to the `__typename` datastore field via `name_in_index`, and relies on `__typename` being present in all index mappings — including single-type indices, which now store it as a `constant_keyword` (added in block#1171). Generated with Claude Code
f7397e4 to
06f5490
Compare
I did my best to clearly explain this here in supports_filtering_and_aggregation.rb |
We discussed this live and you convinced me it's likely not what users would expect. An idea for potential later implementation may be a new operator instead of |
Closes #1024
Finishes the work @myronmarston started in #1027.
Adds a
_typenamefilter field to all interface and union type filter inputs, allowing clients to filter by concrete subtype:{ distribution_channels(filter: { _typename: { equal_to_any_of: ["OnlineStore"] } }) { ... } }What this adds on top of #1027:
name_in_index: "__typename"on the filter field soFilterArgsTranslatormaps_typename→__typenamein the datastore query at runtimename_in_indexentry in runtime metadata for each abstractFilterInputtype_typename→__typenametranslation infilters_spec.rb_typenamefiltering on: top-level abstract type queries (distribution_channels,retailers) where multiple concrete types share an index, embedded union/interface fields (inventor,named_inventor), and aggregationsThis branch was rebased onto main after #1171 merged, which now allows
__typenamedatastore filters to match single-type indexes (indexes that store only a single concrete type). So now the acceptance test covers these cases likeequal_to_any_of: ["OnlineStore", "PhysicalStore"], for example.I decided to defer the optimization idea to use the
_typenamefilter to limit the set ofsearch_index_definitionssince that seems like a pure optimization that could be done separately to prevent bloating this PR with additional complexity not strictly required for working_typenamefilters (the issue described in #1024).