Skip to content

Commit

Permalink
feat(return): add distinct option
Browse files Browse the repository at this point in the history
Return now supports an additional options parameter that contains a `distinct` flag. Setting it to
true will cause the return clause to only return unique rows. In addition, the `returnDistinct`
method was added to the query interface as a shortcut to `return(..., { distinct: true }).

fix #90
  • Loading branch information
jamesfer committed Aug 25, 2019
1 parent 769c327 commit 205960a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 9 deletions.
18 changes: 15 additions & 3 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { AnyConditions } from './clauses/where-utils';
import { Clause } from './clause';
import { RemoveProperties } from './clauses/remove';
import { Union } from './clauses/union';
import { ReturnOptions } from './clauses/return';

/**
* @internal
Expand Down Expand Up @@ -619,13 +620,24 @@ export abstract class Builder<Q> extends SetBlock<Q> {
*
* You can also pass an array of any of the above methods.
*
* @param {_.Many<Term>} terms
* @returns {Q}
* The return method also accepts a `distinct` option which will cause a `RETURN DISTINCT` to be
* emitted instead.
* ```javascript
* query.return('people', { distinct: true })
* // RETURN DISTINCT people
* ```
*/
return(terms: Many<Term>) {
return(terms: Many<Term>, options?: ReturnOptions) {
return this.continueChainClause(new Return(terms));
}

/**
* Shorthand for `return(terms, { distinct: true });
*/
returnDistinct(terms: Many<Term>) {
return this.return(terms, { distinct: true });
}

/**
* Adds a [skip]{@link https://neo4j.com/docs/developer-manual/current/cypher/clauses/skip}
* clause to the query.
Expand Down
5 changes: 5 additions & 0 deletions src/clauses/return.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@ describe('Return', () => {
const query = new Return('node');
expect(query.build()).to.equal('RETURN node');
});

it('should start with RETURN DISTINCT', () => {
const query = new Return('node', { distinct: true });
expect(query.build()).to.equal('RETURN DISTINCT node');
});
});
});
13 changes: 7 additions & 6 deletions src/clauses/return.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Many } from 'lodash';
import { Term, TermListClause } from './term-list-clause';

export interface ReturnOptions {
distinct?: boolean;
}

export class Return extends TermListClause {
/**
* Creates a return clause
* @param {string|object|array<string|object>|} terms [description]
*/
constructor(terms: Many<Term>) {
constructor(terms: Many<Term>, protected options: ReturnOptions = {}) {
super(terms);
}

build() {
return `RETURN ${super.build()}`;
const distinct = this.options.distinct ? ' DISTINCT' : '';
return `RETURN${distinct} ${super.build()}`;
}
}
1 change: 1 addition & 0 deletions tests/connection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ describe('Connection', () => {
createNode: () => connection.createNode('Node'),
create: () => connection.create(new NodePattern('Node')),
return: () => connection.return('node'),
returnDistinct: () => connection.returnDistinct('node'),
remove: () => connection.remove({ properties: { node: ['prop1', 'prop2'] } }),
removeProperties: () => connection.removeProperties({ node: ['prop1', 'prop2'] }),
removeLabels: () => connection.removeLabels({ node: 'label' }),
Expand Down

0 comments on commit 205960a

Please sign in to comment.