-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3792268
commit 229765f
Showing
6 changed files
with
276 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
'use strict'; | ||
|
||
const isNil = require('lodash.isnil'); | ||
|
||
const { Query, util: { checkType } } = require('../../core'); | ||
|
||
/** | ||
* Returns any documents that match with at least one or more of the provided | ||
* terms. The terms are not analyzed and thus must match exactly. The number of | ||
* terms that must match varies per document and is either controlled by a | ||
* minimum should match field or computed per document in a minimum should match | ||
* script. | ||
* | ||
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-set-query.html) | ||
* | ||
* NOTE: This query was added in elasticsearch v6.1. | ||
* | ||
* @example | ||
* const qry = esb.termsSetQuery('codes', ['abc', 'def', 'ghi']) | ||
* .minimumShouldMatchField('required_matches') | ||
* | ||
* @param {string=} field | ||
* @param {Array<string|number|boolean>|string|number=} terms | ||
* | ||
* @extends Query | ||
*/ | ||
class TermsSetQuery extends Query { | ||
// eslint-disable-next-line require-jsdoc | ||
constructor(field, terms) { | ||
super('terms_set'); | ||
|
||
this._queryOpts.terms = []; | ||
|
||
if (!isNil(field)) this._field = field; | ||
if (!isNil(terms)) { | ||
if (Array.isArray(terms)) this.terms(terms); | ||
else this.term(terms); | ||
} | ||
} | ||
|
||
/** | ||
* Sets the field to search on. | ||
* | ||
* @param {string} field | ||
* @returns {TermsSetQuery} returns `this` so that calls can be chained. | ||
*/ | ||
field(field) { | ||
this._field = field; | ||
return this; | ||
} | ||
|
||
/** | ||
* Append given term to set of terms to run Terms Set Query with. | ||
* | ||
* @param {string|number|boolean} term | ||
* @returns {TermsSetQuery} returns `this` so that calls can be chained | ||
*/ | ||
term(term) { | ||
this._queryOpts.terms.push(term); | ||
return this; | ||
} | ||
|
||
/** | ||
* Specifies the terms to run query for. | ||
* | ||
* @param {Array<string|number|boolean>} terms Terms set to run query for. | ||
* @returns {TermsSetQuery} returns `this` so that calls can be chained | ||
* @throws {TypeError} If `terms` is not an instance of Array | ||
*/ | ||
terms(terms) { | ||
checkType(terms, Array); | ||
|
||
this._queryOpts.terms = this._queryOpts.terms.concat(terms); | ||
return this; | ||
} | ||
|
||
/** | ||
* Controls the number of terms that must match per document. | ||
* | ||
* @param {string} fieldName | ||
* @returns {TermsSetQuery} returns `this` so that calls can be chained | ||
*/ | ||
minimumShouldMatchField(fieldName) { | ||
this._queryOpts.minimum_should_match_field = fieldName; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the `script` for query. It controls how many terms are required to | ||
* match in a more dynamic way. | ||
* | ||
* The `params.num_terms` parameter is available in the script to indicate | ||
* the number of terms that have been specified. | ||
* | ||
* @example | ||
* const qry = esb.termsSetQuery('codes', ['abc', 'def', 'ghi']) | ||
* .minimumShouldMatchScript({ | ||
* source: "Math.min(params.num_terms, doc['required_matches'].value)" | ||
* }) | ||
* | ||
* @param {Script|string|Object} script | ||
* @returns {ScriptQuery} returns `this` so that calls can be chained. | ||
*/ | ||
minimumShouldMatchScript(script) { | ||
this._queryOpts.minimum_should_match_script = script; | ||
return this; | ||
} | ||
|
||
/** | ||
* Override default `toJSON` to return DSL representation of the term level query | ||
* class instance. | ||
* | ||
* @override | ||
* @returns {Object} returns an Object which maps to the elasticsearch query DSL | ||
*/ | ||
toJSON() { | ||
return { | ||
[this.queryType]: { [this._field]: this._queryOpts } | ||
}; | ||
} | ||
} | ||
|
||
module.exports = TermsSetQuery; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import test from 'ava'; | ||
import { TermsSetQuery } from '../../src'; | ||
import { | ||
illegalParamType, | ||
nameFieldExpectStrategy, | ||
makeSetsOptionMacro | ||
} from '../_macros'; | ||
|
||
const getInstance = () => new TermsSetQuery('my_field'); | ||
|
||
const setsOption = makeSetsOptionMacro( | ||
getInstance, | ||
nameFieldExpectStrategy('terms_set', { terms: [] }) | ||
); | ||
|
||
test(illegalParamType, getInstance(), 'terms', 'Array'); | ||
test(setsOption, 'term', { | ||
param: 'my-value', | ||
propValue: ['my-value'], | ||
keyName: 'terms' | ||
}); | ||
test(setsOption, 'terms', { | ||
param: ['my-value-1', 'my-value-2'], | ||
spread: false | ||
}); | ||
test(setsOption, 'minimumShouldMatchField', { param: 'required_matches' }); | ||
test(setsOption, 'minimumShouldMatchScript', { | ||
param: { | ||
source: "Math.min(params.num_terms, doc['required_matches'].value)" | ||
} | ||
}); | ||
|
||
test('constructor sets arguments', t => { | ||
let valueA = new TermsSetQuery('my_field', 'my-value').toJSON(); | ||
let valueB = new TermsSetQuery() | ||
.field('my_field') | ||
.term('my-value') | ||
.toJSON(); | ||
t.deepEqual(valueA, valueB); | ||
|
||
let expected = { | ||
terms_set: { | ||
my_field: { terms: ['my-value'] } | ||
} | ||
}; | ||
t.deepEqual(valueA, expected); | ||
|
||
valueA = new TermsSetQuery('my_field', [ | ||
'my-value-1', | ||
'my-value-2' | ||
]).toJSON(); | ||
valueB = new TermsSetQuery() | ||
.field('my_field') | ||
.terms(['my-value-1', 'my-value-2']) | ||
.toJSON(); | ||
t.deepEqual(valueA, valueB); | ||
|
||
expected = { | ||
terms_set: { | ||
my_field: { | ||
terms: ['my-value-1', 'my-value-2'] | ||
} | ||
} | ||
}; | ||
t.deepEqual(valueA, expected); | ||
}); |