Skip to content

Commit

Permalink
fix(QueryDSL): Beautifying and small refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
nodkz committed Mar 11, 2017
1 parent 9cc9e57 commit 8b8889e
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 86 deletions.
96 changes: 63 additions & 33 deletions src/ElasticDSL/Query/Bool.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,70 @@

import { InputTypeComposer } from 'graphql-compose';
import { getQueryITC } from './Query';
import { getTypeName, getOrSetType } from "../../utils";
import { getTypeName, getOrSetType, desc } from "../../utils";

export function getBoolITC(opts = {}): InputTypeComposer {
const typeName = getTypeName('QueryBool', opts);
export function getBoolITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('QueryBool', opts);
const description = desc(`
A query that matches documents matching boolean combinations
of other queries. The bool query maps to Lucene BooleanQuery.
It is built using one or more boolean clauses, each clause
with a typed occurrence.
`);

return getOrSetType(typeName, () => {
const BoolITC = InputTypeComposer.create(typeName);
BoolITC.setDescription('A query that matches documents matching boolean combinations of other queries. The bool query maps to Lucene BooleanQuery. It is built using one or more boolean clauses, each clause with a typed occurrence. ');
BoolITC.setFields({
must: {
type: () => getQueryITC(opts),
description: 'The clause (query) must appear in matching documents and will contribute to the score.',
return getOrSetType(name, () =>
// $FlowFixMe
InputTypeComposer.create({
name,
description,
fields: {
must: {
type: () => getQueryITC(opts),
description: desc(`
The clause (query) must appear in matching documents
and will contribute to the score.
`),
},
filter: {
type: () => getQueryITC(opts),
description: desc(`
The clause (query) must appear in matching documents.
However unlike must the score of the query will be ignored.
Filter clauses are executed in filter context, meaning
that scoring is ignored and clauses are considered for caching.
`),
},
should: {
type: () => getQueryITC(opts),
description: desc(`
The clause (query) should appear in the matching document.
In a boolean query with no must or filter clauses,
one or more should clauses must match a document.
The minimum number of should clauses to match can be set
using the minimum_should_match parameter.
`),
},
minimum_should_match: {
type: 'Int',
description: desc(`
The minimum number of should clauses to match can be set using
the minimum_should_match parameter.
`),
},
must_not: {
type: () => getQueryITC(opts),
description: desc(`
The clause (query) must not appear in the matching documents.
Clauses are executed in filter context meaning that scoring
is ignored and clauses are considered for caching.
Because scoring is ignored, a score of 0 for all documents
is returned.
`),
},
boost: {
type: 'Float',
},
},
filter: {
type: () => getQueryITC(opts),
description: 'The clause (query) must appear in matching documents. However unlike must the score of the query will be ignored. Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.',
},
should: {
type: () => getQueryITC(opts),
description: 'The clause (query) should appear in the matching document. In a boolean query with no must or filter clauses, one or more should clauses must match a document. The minimum number of should clauses to match can be set using the minimum_should_match parameter.',
},
minimum_should_match: {
type: 'Int',
description: 'The minimum number of should clauses to match can be set using the minimum_should_match parameter.',
},
must_not: {
type: () => getQueryITC(opts),
description: 'The clause (query) must not appear in the matching documents. Clauses are executed in filter context meaning that scoring is ignored and clauses are considered for caching. Because scoring is ignored, a score of 0 for all documents is returned.',
},
boost: {
type: 'Float',
},
});

return BoolITC;
});
})
);
}
27 changes: 27 additions & 0 deletions src/ElasticDSL/Query/Match.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* @flow */

import { InputTypeComposer } from 'graphql-compose';
import { getTypeName, getOrSetType, desc } from '../../utils';

export function getMatchITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('QueryTerm', opts);
const description = desc(`
Match Query accept text/numerics/dates, analyzes them, and constructs a query.
[Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html)
`);

if (false) {
return getOrSetType(name, () =>
InputTypeComposer.create({
name,
description,
fields: {},
}));
}

// $FlowFixMe
return {
type: 'JSON',
description,
};
}
31 changes: 18 additions & 13 deletions src/ElasticDSL/Query/MatchAll.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
/* @flow */

import { InputTypeComposer } from 'graphql-compose';
import { getTypeName, getOrSetType } from '../../utils';
import { getTypeName, getOrSetType, desc } from '../../utils';

export function getMatchAllITC(opts = {}): InputTypeComposer {
const typeName = getTypeName('QueryMatchAll', opts);
export function getMatchAllITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('QueryMatchAll', opts);
const description = desc(`
The most simple query, which matches all documents,
giving them all a _score of 1.0.
`);

return getOrSetType(typeName, () => {
const MatchAllITC = InputTypeComposer.create(typeName);
MatchAllITC.setDescription('The most simple query, which matches all documents, giving them all a _score of 1.0.');
MatchAllITC.setFields({
boost: {
type: 'Float',
return getOrSetType(name, () =>
// $FlowFixMe
InputTypeComposer.create({
name,
description,
fields: {
boost: {
type: 'Float',
},
},
});

return MatchAllITC;
});
})
);
}
46 changes: 23 additions & 23 deletions src/ElasticDSL/Query/Query.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@
import { InputTypeComposer } from 'graphql-compose';
import { getBoolITC } from './Bool';
import { getMatchAllITC } from './MatchAll';
import { getTypeName, getOrSetType } from '../../utils';
import { getTermITC } from './Term';
import { getTermsITC } from './Terms';
import { getMatchITC } from './Match';
import { getTypeName, getOrSetType, desc } from '../../utils';

export function getQueryITC(opts = {}): InputTypeComposer {
const typeName = getTypeName('Query', opts);
export function getQueryITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('Query', opts);
const description = desc(`
Elasticsearch provides a full Query DSL based on JSON to define queries.
[Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html)
`);

return getOrSetType(typeName, () => {
const QueryITC = InputTypeComposer.create(typeName);
QueryITC.setFields({
bool: () => getBoolITC(opts),
match_all: () => getMatchAllITC(opts),
term: {
type: 'JSON',
description: 'The term query finds documents that contain the exact term specified in the inverted index. { fieldName: value } or { fieldName: { value: value, boost: 2.0 } }',
return getOrSetType(name, () =>
// $FlowFixMe
InputTypeComposer.create({
name,
description,
fields: {
bool: () => getBoolITC(opts),
match_all: () => getMatchAllITC(opts),
term: () => getTermITC(opts),
terms: () => getTermsITC(opts),
match: () => getMatchITC(opts),
},
terms: {
type: 'JSON',
description: 'Filters documents that have fields that match any of the provided terms (not analyzed). { fieldName: [values] }',
},
match: {
type: 'JSON',
description: '',
},
});

return QueryITC;
});
})
);
}
29 changes: 29 additions & 0 deletions src/ElasticDSL/Query/Term.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* @flow */

import { InputTypeComposer } from 'graphql-compose';
import { getTypeName, getOrSetType, desc } from '../../utils';

export function getTermITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('QueryTerm', opts);
const description = desc(`
Find documents which contain the exact term specified
in the field specified.
{ fieldName: value } or { fieldName: { value: value, boost: 2.0 } }
[Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html)
`);

if (false) {
return getOrSetType(name, () =>
InputTypeComposer.create({
name,
description,
fields: {},
}));
}

// $FlowFixMe
return {
type: 'JSON',
description,
};
}
28 changes: 28 additions & 0 deletions src/ElasticDSL/Query/Terms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* @flow */

import { InputTypeComposer } from 'graphql-compose';
import { getTypeName, getOrSetType, desc } from '../../utils';

export function getTermsITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('QueryTerms', opts);
const description = desc(`
Filters documents that have fields that match any of
the provided terms (not analyzed). { fieldName: [values] }
[Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html)
`);

if (false) {
return getOrSetType(name, () =>
InputTypeComposer.create({
name,
description,
fields: {},
}));
}

// $FlowFixMe
return {
type: 'JSON',
description,
};
}
31 changes: 17 additions & 14 deletions src/ElasticDSL/SearchBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@

import { InputTypeComposer } from 'graphql-compose';
import { getQueryITC } from './Query/Query';
import { getTypeName, getOrSetType } from '../utils';
import { getTypeName, getOrSetType, desc } from '../utils';

export function getSearchBodyITC(opts = {}): InputTypeComposer {
const typeName = getTypeName('SearchBody', opts);
export function getSearchBodyITC(opts: mixed = {}): InputTypeComposer {
const name = getTypeName('SearchBody', opts);
const description = desc(`
The search request can be executed with a search DSL, which includes
the [Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html),
within its body.
`);

return getOrSetType(typeName, () => {
const SearchBodyITC = InputTypeComposer.create(typeName);
SearchBodyITC.setDescription(
'A query that matches documents matching boolean combinations of other queries. The bool query maps to Lucene BooleanQuery. It is built using one or more boolean clauses, each clause with a typed occurrence. '
);
SearchBodyITC.setFields({
query: () => getQueryITC(opts),
});

return SearchBodyITC;
});
return getOrSetType(name, () =>
// $FlowFixMe
InputTypeComposer.create({
name,
description,
fields: {
query: () => getQueryITC(opts),
},
}));
}
1 change: 1 addition & 0 deletions src/typeStorage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* @flow */

import { isFunction } from 'graphql-compose';

class TypeStorage extends Map {
Expand Down
15 changes: 12 additions & 3 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
/* @flow */

import typeStorage from './typeStorage';

export function getTypeName(name: string, opts: any): string {
return `${opts && opts.prefix || 'Elastic'}${name}${opts && opts.postfix || ''}`;
return `${(opts && opts.prefix) || 'Elastic'}${name}${(opts && opts.postfix) || ''}`;
}

export function getOrSetType<T>(typeName: string, typeOrThunk: (() => T) | T): T {
// $FlowFixMe
const type: T = typeStorage.getOrSet(typeName, typeOrThunk);
return type;
}

export function getOrSetType<T>(typeName: string, typeOrThunk: T | () => T): T {
return typeStorage.getOrSet(typeName, typeOrThunk);
// Remove newline multiline in descriptions
export function desc(str: string): string {
return str.replace(/\n\s+/, ' ');
}

0 comments on commit 8b8889e

Please sign in to comment.