Skip to content

Commit a989f48

Browse files
committed
feat(Query): Queries now support fields from mapping
1 parent 7c90119 commit a989f48

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1555
-698
lines changed

examples/elastic50/index.js

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,40 @@
1+
/* @flow */
2+
/* eslint-disable no-console */
3+
14
import express from 'express';
25
import graphqlHTTP from 'express-graphql';
36
import { GraphQLSchema, GraphQLObjectType, GraphQLString } from 'graphql';
47
import elasticsearch from 'elasticsearch';
58
import ElasticApiParser from '../../src/ElasticApiParser'; // or import { ElasticApiParser } from 'graphql-compose-elasticsearch';
9+
import createSearchResolver from '../../src/resolvers/search';
10+
import fieldMap from '../../src/__mocks__/cvMapping';
11+
import { inputPropertiesToGraphQLTypes } from '../../src/mappingConverter';
612

713
const expressPort = process.env.port || process.env.PORT || 9201;
814

915
const generatedSchema = new GraphQLSchema({
1016
query: new GraphQLObjectType({
1117
name: 'Query',
1218
fields: {
19+
// $FlowFixMe
20+
cv: createSearchResolver(
21+
inputPropertiesToGraphQLTypes(fieldMap),
22+
undefined,
23+
new elasticsearch.Client({
24+
host: 'http://localhost:9200',
25+
apiVersion: '5.0',
26+
log: 'trace',
27+
}),
28+
{
29+
prefix: 'Cv',
30+
}
31+
).getFieldConfig(),
1332
// see node_modules/elasticsearch/src/lib/apis/ for available versions
14-
1533
elastic50: {
1634
description: 'Elastic v5.0',
1735
type: new GraphQLObjectType({
1836
name: 'Elastic50',
37+
// $FlowFixMe
1938
fields: new ElasticApiParser({
2039
version: '5_0',
2140
prefix: 'Elastic50',
@@ -28,12 +47,14 @@ const generatedSchema = new GraphQLSchema({
2847
},
2948
},
3049
resolve: (src, args, context) => {
31-
// eslint-disable-next-line no-param-reassign
32-
context.elasticClient = new elasticsearch.Client({
33-
host: args.host,
34-
apiVersion: '5.0',
35-
log: 'trace',
36-
});
50+
if (typeof context === 'object') {
51+
// eslint-disable-next-line no-param-reassign
52+
context.elasticClient = new elasticsearch.Client({
53+
host: args.host,
54+
apiVersion: '5.0',
55+
log: 'trace',
56+
});
57+
}
3758
return {};
3859
},
3960
},

src/ElasticApiParser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ export default class ElasticApiParser {
239239

240240
generateFieldConfig(
241241
methodName: string,
242-
methodArgs: { [paramName: string]: mixed }
242+
methodArgs?: { [paramName: string]: mixed }
243243
): GraphQLFieldConfig<*, *> {
244244
if (!methodName) {
245245
throw new Error(`You should provide Elastic search method.`);

src/__mocks__/cvMapping.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ export default {
321321
},
322322
},
323323
},
324+
location: {
325+
type: 'geo_point',
326+
},
324327
},
325328
},
326329
middlename: {

src/composeWithElastic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TypeComposer, InputTypeComposer } from 'graphql-compose';
1+
import { TypeComposer } from 'graphql-compose';
22
import {
33
convertToSourceTC,
44
inputPropertiesToGraphQLTypes,

src/elasticDSL/Aggs/converter.js renamed to src/elasticDSL/Aggs/Aggs.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import { getAggBlockITC } from './AggBlock';
2+
3+
export function getAggsITC(opts: mixed) {
4+
return [getAggBlockITC(opts)];
5+
}
6+
17
export type ElasticAggsT = {
28
[outputFieldName: string]: ElasticAggsRulesT,
39
};
@@ -14,17 +20,17 @@ export type GqlAggBlock = {
1420

1521
export type GqlAggRules = {
1622
[aggOperationName: string]: mixed,
17-
aggs: GqlAggBlock,
23+
aggs: GqlAggBlock[],
1824
};
1925

20-
export default function argsBlockConverter(
21-
args: { [argName: string]: any }
26+
export function prepareAggsInResolve(
27+
aggs: GqlAggBlock[],
28+
fieldMap: any // eslint-disable-line
2229
): { [argName: string]: any } {
23-
if (args && args.body && Array.isArray(args.body.aggs)) {
24-
const aggs: GqlAggBlock[] = args.body.aggs;
25-
args.body.aggs = convertAggsBlocks(aggs); // eslint-disable-line
30+
if (Array.isArray(aggs)) {
31+
return convertAggsBlocks(aggs);
2632
}
27-
return args;
33+
return aggs;
2834
}
2935

3036
export function convertAggsBlocks(blockList: GqlAggBlock[]): ElasticAggsT {
@@ -43,6 +49,7 @@ export function convertAggsRules(rules: GqlAggRules): ElasticAggsRulesT {
4349
if (key === 'aggs' && rules.aggs) {
4450
result.aggs = convertAggsBlocks(rules.aggs);
4551
} else {
52+
// $FlowFixMe
4653
result[key] = rules[key];
4754
}
4855
});
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* @flow */
2+
3+
import {
4+
printSchema,
5+
GraphQLSchema,
6+
GraphQLObjectType,
7+
GraphQLInt,
8+
} from 'graphql';
9+
import { TypeMapper } from 'graphql-compose';
10+
import {
11+
getAggsITC,
12+
prepareAggsInResolve,
13+
convertAggsBlocks,
14+
convertAggsRules,
15+
} from '../Aggs';
16+
17+
describe('AGGS args converter', () => {
18+
it('Aggs DSL', () => {
19+
const schema = new GraphQLSchema({
20+
query: new GraphQLObjectType({
21+
name: 'RootQuery',
22+
fields: {
23+
search: {
24+
// $FlowFixMe
25+
args: TypeMapper.convertArgConfigMap({
26+
body: {
27+
type: getAggsITC({
28+
prefix: 'Elastic_',
29+
postfix: '_50',
30+
}),
31+
},
32+
}),
33+
type: GraphQLInt,
34+
},
35+
},
36+
}),
37+
});
38+
expect(printSchema(schema)).toMatchSnapshot();
39+
});
40+
41+
it('convertAggsRules()', () => {
42+
expect(convertAggsRules({ some: { field: 1 } })).toEqual({
43+
some: { field: 1 },
44+
});
45+
});
46+
47+
it('convertAggsBlocks()', () => {
48+
expect(
49+
convertAggsBlocks([
50+
{ key: 'field1', value: {} },
51+
{ key: 'field2', value: {} },
52+
])
53+
).toEqual({
54+
field1: {},
55+
field2: {},
56+
});
57+
});
58+
59+
it('should convert recursively aggs', () => {
60+
expect(
61+
convertAggsBlocks([
62+
{ key: 'field1', value: { aggs: [{ key: 'field2', value: {} }] } },
63+
])
64+
).toEqual({ field1: { aggs: { field2: {} } } });
65+
});
66+
67+
it('prepareAggsInResolve()', () => {
68+
expect(
69+
prepareAggsInResolve([
70+
{ key: 'field1', value: { term: 'a' } },
71+
{ key: 'field2', value: { term: 'b' } },
72+
])
73+
).toEqual({
74+
field1: { term: 'a' },
75+
field2: { term: 'b' },
76+
});
77+
});
78+
});

0 commit comments

Comments
 (0)