diff --git a/src/index.d.ts b/src/index.d.ts index 9a01a76..db3b674 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -3268,6 +3268,86 @@ declare namespace esb { */ export function distanceFeatureQuery(field?: string): DistanceFeatureQuery; + /** + * The `rank_feature` query boosts the relevance score on the numeric value of + * document with a rank_feature/rank_features field. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-rank-feature-query.html) + * + * NOTE: This query was added in elasticsearch v7.0. + * + * @example + * const query = new RankFeatureQuery('rank_feature_field'); + * query + * .linear() + * .toJSON(); + * @param {string} field The field inside the document to be used in the query + * @return {RankFeatureQuery} + */ + export class RankFeatureQuery extends Query { + constructor(field?: string); + + /** + * Sets the field for the `distance_feature` query + * @param {string} fieldName Name of the field inside the document + * @returns {DistanceFeatureQuery} Instance of the query + */ + field(fieldName: string): RankFeatureQuery; + + /** + * Linear function to boost relevance scores based on the value of the rank feature field + * @returns {RankFeatureQuery} + */ + linear() : RankFeatureQuery; + + /** + * Saturation function to boost relevance scores based on the value of the rank feature field. + * Uses a default pivot value computed by Elasticsearch. + * @returns {RankFeatureQuery} + */ + saturation() : RankFeatureQuery; + + /** + * Saturation function to boost relevance scores based on the value of the rank feature field. + * @param {number} pivot + * @returns {RankFeatureQuery} + */ + saturationPivot(pivot : number) : RankFeatureQuery; + + /** + * The log function gives a score equal to log(scaling_factor + S), where S + * is the value of the rank feature field and scaling_factor is a configurable + * scaling factor. + * @param {number} scaling_factor + * @returns {RankFeatureQuery} + */ + log(scalingFactor : number) : RankFeatureQuery; + + /** + * The sigmoid function extends the saturation function with a configurable exponent. + * @param {number} pivot + * @param {number} exponent + * @returns {RankFeatureQuery} + */ + sigmoid(pivot : number, exponent : number) : RankFeatureQuery + } + + /** + * The `rank_feature` query boosts the relevance score on the numeric value of + * document with a rank_feature/rank_features field. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-rank-feature-query.html) + * + * @example + * const query = new RankFeatureQuery('rank_feature_field'); + * query + * .linear() + * .toJSON(); + * @param {string} field The field inside the document to be used in the query + * @return {RankFeatureQuery} + */ + export function rankFeatureQuery(field?: string): RankFeatureQuery; + /** * Interface-like class used to group and identify various implementations of Span queries. * diff --git a/src/index.js b/src/index.js index af7f821..92e27bc 100644 --- a/src/index.js +++ b/src/index.js @@ -73,7 +73,8 @@ const { ScriptQuery, ScriptScoreQuery, PercolateQuery, - DistanceFeatureQuery + DistanceFeatureQuery, + RankFeatureQuery }, spanQueries: { SpanTermQuery, @@ -304,6 +305,9 @@ exports.percolateQuery = constructorWrapper(PercolateQuery); exports.DistanceFeatureQuery = DistanceFeatureQuery; exports.distanceFeatureQuery = constructorWrapper(DistanceFeatureQuery); +exports.RankFeatureQuery = RankFeatureQuery; +exports.rankFeatureQuery = constructorWrapper(RankFeatureQuery); + /* ============ ============ ============ */ /* ============ Span Queries ============ */ /* ============ ============ ============ */ diff --git a/src/queries/specialized-queries/index.js b/src/queries/specialized-queries/index.js index a760b86..8d21424 100644 --- a/src/queries/specialized-queries/index.js +++ b/src/queries/specialized-queries/index.js @@ -5,3 +5,4 @@ exports.ScriptQuery = require('./script-query'); exports.ScriptScoreQuery = require('./script-score-query'); exports.PercolateQuery = require('./percolate-query'); exports.DistanceFeatureQuery = require('./distance-feature-query'); +exports.RankFeatureQuery = require('./rank-feature-query'); diff --git a/src/queries/specialized-queries/rank-feature-query.js b/src/queries/specialized-queries/rank-feature-query.js new file mode 100644 index 0000000..1b982ec --- /dev/null +++ b/src/queries/specialized-queries/rank-feature-query.js @@ -0,0 +1,98 @@ +'use strict'; + +const { Query } = require('../../core'); +const isNil = require('lodash.isnil'); + +/** + * The rank_feature query boosts the relevance score on the numeric value of + * document with a rank_feature/rank_features field. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-rank-feature-query.html) + * + * NOTE: This query was added in elasticsearch v7.0. + * + * @example + * const query = new RankFeatureQuery('rank_feature_field'); + * query + * .linear() + * .toJSON(); + * @param {string} field The field inside the document to be used in the query + * @extends Query + */ +class RankFeatureQuery extends Query { + /** + * @param {string} field The field inside the document to be used in the query + */ + constructor(field) { + super('rank_feature'); + if (!isNil(field)) this._queryOpts.field = field; + } + + /** + * Sets the field for the `rank_feature` query + * @param {string} fieldName Name of the field inside the document + * @returns {RankFeatureQuery} Instance of the distance feature query + */ + field(fieldName) { + this._queryOpts.field = fieldName; + return this; + } + + /** + * Linear function to boost relevance scores based on the value of the rank feature field + * @returns {RankFeatureQuery} + */ + linear() { + this._queryOpts.linear = {}; + return this; + } + + /** + * Saturation function to boost relevance scores based on the value of the rank feature field. + * Uses a default pivot value computed by Elasticsearch. + * @returns {RankFeatureQuery} + */ + saturation() { + this._queryOpts.saturation = {}; + return this; + } + + /** + * Saturation function to boost relevance scores based on the value of the rank feature field. + * @param {number} pivot + * @returns {RankFeatureQuery} + */ + saturationPivot(pivot) { + this._queryOpts.saturation = {}; + this._queryOpts.saturation.pivot = pivot; + return this; + } + + /** + * The log function gives a score equal to log(scaling_factor + S), where S + * is the value of the rank feature field and scaling_factor is a configurable + * scaling factor. + * @param {number} scaling_factor + * @returns {RankFeatureQuery} + */ + log(scalingFactor) { + this._queryOpts.log = {}; + this._queryOpts.log.scaling_factor = scalingFactor; + return this; + } + + /** + * The sigmoid function extends the saturation function with a configurable exponent. + * @param {number} pivot + * @param {number} exponent + * @returns {RankFeatureQuery} + */ + sigmoid(pivot, exponent) { + this._queryOpts.sigmoid = {}; + this._queryOpts.sigmoid.pivot = pivot; + this._queryOpts.sigmoid.exponent = exponent; + return this; + } +} + +module.exports = RankFeatureQuery; diff --git a/test/queries-test/rank-feature.test.js b/test/queries-test/rank-feature.test.js new file mode 100644 index 0000000..2c5fd0a --- /dev/null +++ b/test/queries-test/rank-feature.test.js @@ -0,0 +1,86 @@ +import test from 'ava'; +import { RankFeatureQuery } from '../../src'; + +test('Should test no args rank feature query', t => { + const value = new RankFeatureQuery('my_field').toJSON(); + const expected = { + rank_feature: { + field: 'my_field' + } + }; + t.deepEqual(value, expected); +}); + +test('Should test with fieldName', t => { + const value = new RankFeatureQuery().field('my_field').toJSON(); + const expected = { + rank_feature: { + field: 'my_field' + } + }; + t.deepEqual(value, expected); +}); + +test('Should test linear rank feature query', t => { + const value = new RankFeatureQuery('my_field').linear().toJSON(); + const expected = { + rank_feature: { + field: 'my_field', + linear: {} + } + }; + t.deepEqual(value, expected); +}); + +test('Should test saturation rank feature query', t => { + const value = new RankFeatureQuery('my_field').saturation().toJSON(); + const expected = { + rank_feature: { + field: 'my_field', + saturation: {} + } + }; + t.deepEqual(value, expected); +}); + +test('Should test saturation with pivot rank feature query', t => { + const value = new RankFeatureQuery('my_field') + .saturationPivot(123) + .toJSON(); + const expected = { + rank_feature: { + field: 'my_field', + saturation: { + pivot: 123 + } + } + }; + t.deepEqual(value, expected); +}); + +test('Should test sigmoid rank feature query', t => { + const value = new RankFeatureQuery('my_field').sigmoid(2, 0.6).toJSON(); + const expected = { + rank_feature: { + field: 'my_field', + sigmoid: { + pivot: 2, + exponent: 0.6 + } + } + }; + t.deepEqual(value, expected); +}); + +test('Should test logarithmic rank feature query', t => { + const value = new RankFeatureQuery('my_field').log(2).toJSON(); + const expected = { + rank_feature: { + field: 'my_field', + log: { + scaling_factor: 2 + } + } + }; + t.deepEqual(value, expected); +});