elastic query generated for sort by enum
amarflybot opened this issue · comments
@nodkz , I see a small issue with the elastic query generated at version:
Wrong query produced for sort: [order_id__asc],
, where order_id__asc
is a enum.
After the change made in #214, Elastic Query generated was
"sort": [
"order_id__asc"
]
Before the change in #214
Correct query generated was:
"sort": [
{
"order_id": "asc"
}
]
Originally posted by @amarflybot in graphql-compose/graphql-compose#214 (comment)
Sort functionality for the below code works fine:
const generatedSchema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
ecommerceSearch: EcommerceEsTC.getResolver('search').getFieldConfig(),
ecommercePagination: EcommerceEsTC.getResolver('searchPagination').getFieldConfig(),
ecommerceSearchConnection: EcommerceEsTC.getResolver('searchConnection').getFieldConfig()
},
}),
});
const server = new ApolloServer({
schema: buildFederatedSchema(generatedSchema)
});
The above code generates the sort:
"sort": [
{
"order_id": "asc"
}
]
The new code:
const extensionSdl = gql`
extend type Content @key(fields: "id") {
id: ID! @external
ecommerces: [ecommerceecommerce]
}
extend type Director @key(fields: "id") {
id: ID! @external
geoips: [ecommerceecommerceGeoip]
}
`;
function findEcommerceByContentId(id: number) {
}
const resolvers = {
Content: {
ecommerces(content) {
console.log(content);
return findEcommerceByContentId(content.id);/*find ecommerces by content id*/
}
},
Director: {
geoips(content) {
console.log(content);
return findEcommerceByContentId(content.id);/*find ecommerces by content id*/
}
}
};
let composer = schemaComposer.toSDL({exclude: ['Boolean','String']});
const app = express();
let resolveMethods = schemaComposer.getResolveMethods();
const server = new ApolloServer({
schema: buildFederatedSchema([
{typeDefs: gql(composer), resolvers: resolveMethods},
{typeDefs: extensionSdl, resolvers: resolvers}
])
});
Generates the wrong code:
"sort": [
"order_id__asc"
]
I've just updated dependencies and this lib correctly works with new graphql-compose 7.11.0. It passes all tests. The error somewhere in graphql-compose methods or in a way how we combine schemas.
Will be nice if you create a PR with error in graphql-compose repo like graphql-compose/graphql-compose#234 It will be nice if you try to write such test case without using graphql-compose-elasticsearch
package.
I need a ready test-case for debugging. When I can write such test-case myself... I don't know (don't have enough free time).
Thanks for the quick reply, I am trying to farmalize the test, will raise the PR.
I am still figuring where from graphql-compose it find the arguments for sort.
graphql-compose
just bunch of helpers for graphql types modification. Other plugins, like graphql-compose-mongoose
reads some models, mappings and generates according to their information the graphql types using graphql-compose
methods.
Hi @nodkz , I have being debugging the graphql-compose and graphql-compose-elastic for a very long time now. But still can't find the place or method that resolves sort: [order_id__asc]
to
"sort": [
{
"order_id": "asc"
}
]
Could you please point me in right direction? I think somehow let resolveMethods = schemaComposer.getResolveMethods({exclude: ['Boolean', 'String', 'ID']});
is responsible.
in the code of Resolver.js:
const resolve = this.getResolve();
return (source, args, context, info) => {
let projection = (0, _projection.getProjectionFromAST)(info);
if (this.projection) {
projection = (0, _deepmerge.deepmerge)(projection, this.projection);
}
if (opts.projection) {
projection = (0, _deepmerge.deepmerge)(projection, opts.projection);
}
return resolve({
source,
args,
context,
info,
projection
});
};
}
Who populates args
?
In this case (source, args, context, info)
all params are populated by graphql itself. So if you provide via graphql-query sort: [order_id__asc]
arg then it transformed internally be Enum type. Enums in graphql has keys
and values
. So from client-side you work with keys
but on the server-side in args your will get values
from enums.
There is the code which generates SortEnum with keys and values
graphql-compose-elasticsearch/src/elasticDSL/Sort.js
Lines 42 to 50 in 8c5b1cb
I worked with elastic about two years ago and for me, it's quite difficult to answer and solve problems. Many things already were forgotten. For now i just keep this lib in sync with graphql-compose changes and improvements. And I will be happy if somebody can bring new features and improvements.
I've just added graphql query test for EnumTypeComposer:
graphql-compose
works correctly. It looks like the problem somewhere in this package. Maybe in resolvers which make calls to elastic.
The tests are fine.
I tried debugging line by line for Elastic Library, everything looks fine.
All Sort Enums are having right values: "labels__timestamp__closed__desc":{"value":{"labels.timestamp.closed":"desc"}}
But Still when the request comes for Sort by labels__timestamp__closed__desc
, Somehow the values is changed to labels__timestamp__closed__desc
, instead of {"labels.timestamp.closed":"desc"}
To Replicate:
In Elastic Execute the query:
POST bug_reports/_doc/1
{
"title": "Results are not sorted correctly.",
"labels": {
"priority": "urgent",
"release": ["v1.2.5", "v1.3.0"],
"timestamp": {
"created": 1541458026,
"closed": 1541457010
}
}
}
Reference index file: https://github.com/amarflybot/graphql-compose-apollo-federation/blob/8bde66dc00ffa6a6c6ed1d69ff3d7a21a8d0eb32/src/index.ts#L129
Agggr, I think that I gotcha your problem.
You are using apollo federation. So you're extracting types as SDL & resolvers. And then pass them to buildFederatedSchema
which reconstructs the schema from scratch. But graphql-compose
does not extract values from Enums in getResolveMethods()
method. See https://www.apollographql.com/docs/graphql-tools/scalars/#internal-values for more details.
I'll make a fix to graphql-compose
for solving this problem.
Please try new graphql-compose (7.12.1). It should fix your problem.
@nodkz , Thanks this fixes the issue.
With some minor errors.
[
{
"message": "Int cannot represent non-integer value: { value: 1, relation: \"eq\" }",
"locations": [
{
"line": 3,
"column": 5
}
],
"path": [
"bgSearchConnection",
"count"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"TypeError: Int cannot represent non-integer value: { value: 1, relation: \"eq\" }",
" at GraphQLScalarType.serializeInt [as serialize] (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/type/scalars.js:43:11)",
" at completeLeafValue (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:635:37)",
" at completeValue (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:579:12)",
" at completeValueCatchingError (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:495:19)",
" at resolveField (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:435:10)",
" at executeFields (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:275:18)",
" at collectAndExecuteSubfields (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:713:10)",
" at completeObjectValue (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:703:10)",
" at completeValue (/Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:591:12)",
" at /Users/amarendrakumar/sandbox/cal-search-service/node_modules/graphql/execution/execute.js:492:16"
]
}
}
}
],
I will check this in some time.
The above issue is because of data. Please close the ticket. Thanks a lot.