From fd2af4a9600167632e21c9c50819b60a3845ba1a Mon Sep 17 00:00:00 2001 From: Luke Taverne Date: Wed, 26 Aug 2015 15:59:23 +0200 Subject: [PATCH] Added support for Solr5 query highlighting. Fixes #130 --- lib/query.js | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/lib/query.js b/lib/query.js index 9bbddefc..6be214c5 100644 --- a/lib/query.js +++ b/lib/query.js @@ -719,3 +719,128 @@ Query.prototype.build = function(){ return this.parameters.join('&'); } +/** + * Set the Query Highlighting parameter. + * + * @param {Object} options - set of options for Highlighting + * @param {Boolean} [options.on=true] - Turn on or off Highlighting + * @param {String|Array} [options.q] - This parameters specifies and overriding query for highlighting. Multiple values specified in an array will be chained together with AND. + * @param {String} [options.qparser] - This parameter specifies the qparser for the hl.q query. + * @param {String|Array} [options.fl] - 'Field list.' Fields to be highlighted. Multiple fields can be entered by providing an array. + * @param {Number} [options.snippets] - This parameter defines the maximum number of snippets to generate per field. Any number of snippets from 0 to this number can be generated per field + * @param {Number} [options.fragsize] - This parameter defines the size, in characters, of the fragments to consider for highlighting. + * @param {Boolean} [options.mergeContiguous] - This parameter instructs Solr to collapse continguous fragments into a single fragment. + * @param {Number} [options.maxAnalyzedChars] - This param specifies the number of characters into a document that Solr should look for suitable snippets. + * @param {Number} [options.maxMultiValuedToExamine] - This param specifies the max number of entries in a multi-valued field to examine before stopping + * @param {Number} [options.maxMultiValuedToMatch] - This param specifies the maximum number of matches in a multi-valued field that are found before stopping. + * @param {String} [options.alternateField] - Specifies a field to be used as a backup default summary if Solr cannot generate a snippet. + * @param {Number} [options.maxAlternateFieldLength] - Specifies the maximum number of characters of the field to return. A number <=0 means the field length is unlimited. + * @param {String} [options.formatter] - Selects a formatter for the highlighted output. At the time of writing, the only legal value is 'simple'. + * @param {String} [options.simplePre] - This parameter defines the string to place before the data to be highlighted. + * @param {String} [options.simplePost] - This parameter defines the string to place after the data to be highlighted. + * @param {String} [options.fragmenter] - Specifies a text snippet generator for highlighted text. Default is 'gap' but 'regex' is another option. + * @param {Boolean} [options.highlightMultiTerm] - Turn on or off MultiTermHighlighting. If True, Solr will use Highlight phrase terms that appear in multiple fields. + * @param {Boolean} [options.requireFieldMatch] - If set to True, this parameter will force Solr to highlight terms only if they appear in the specified field. If false, terms are highlighted in all requested fields regardless of which field matches the query. + * @param {Boolean} [options.usePhraseHighlighter] - If set to True, Solr will use the Lucene SpanScorer class to highlight phrase terms only when they appear within the query phrase in the document. + * @param {Number} [options.regexSlop] - When using the regex fragmenter, this number specifies the factor by which the fragmenter can stray from the ideal fragment size. + * @param {String} [options.regexPattern] - This parameter specifies the regulat expression for fragmenting. + * @param {Number} [options.regexMaxAnalyzedChars] - This parameters specifies the max number of characters to analyze from a field when using the regex fragmenter. + * @param {Boolean} [options.preserveMulti] - If True, multi-valued fields will return all values in the order they were saved in the index. If False, only values that match the highlight request will be returned. + * @param {Boolean} [options.payloads] - If usePhraseHighlighter is True, and the indexed field has payloads but not term vectors, the index payloads will be read into the highlighter's index along with the posting. If you don't want this behavior, you may set this parameter to False and save some memory. + + * + * @return {Query} + * @api public + */ + +Query.prototype.hl = function(options){ + var self = this; + if(options.on === false){ + this.parameters.push('hl=false'); + }else{ + this.parameters.push('hl=true'); + } + if(options.q !== undefined){ + if ( typeof(options.q) === 'string' ){ + this.parameters.push('hl.q=' + encodeURIComponent(options.q)); + }else{ + this.parameters.push('hl.q=' + querystring.stringify(options.q, '%20AND%20',':')); + } + } + if(options.qparser){ + this.parameters.push('hl.qparser=' + encodeURIComponent(options.qparser)); + } + if(options.fl !== undefined){ + if ( typeof(options.fl) === 'string' ){ + this.parameters.push('hl.fl=' + encodeURIComponent(options.fl)); + }else{ + this.parameters.push('hl.fl=' + querystring.stringify(options.fl, '%20AND%20',':')); + } + } + if(options.snippets){ + this.parameters.push('hl.snippets=' + encodeURIComponent(options.snippets)); + } + if(options.fragsize){ + this.parameters.push('hl.fragsize=' + encodeURIComponent(options.fragsize)); + } + if(options.mergeContiguous){ + this.parameters.push('hl.mergeContiguous=' + encodeURIComponent(options.mergeContiguous)); + } + if(options.maxAnalyzedChars){ + this.parameters.push('hl.maxAnalyzedChars=' + encodeURIComponent(options.maxAnalyzedChars)); + } + if(options.maxMultiValuedToExamine){ + this.parameters.push('hl.maxMultiValuedToExamine=' + encodeURIComponent(options.maxMultiValuedToExamine)); + } + if(options.maxMultiValuedToMatch){ + this.parameters.push('hl.maxMultiValuedToMatch=' + encodeURIComponent(options.maxMultiValuedToMatch)); + } + if(options.alternateField){ + this.parameters.push('hl.alternateField=' + encodeURIComponent(options.alternateField)); + } + if(options.maxAlternateFieldLength){ + this.parameters.push('hl.maxAlternateFieldLength=' + encodeURIComponent(options.maxAlternateFieldLength)); + } + if(options.formatter){ + this.parameters.push('hl.formatter=' + encodeURIComponent(options.formatter)); + } + if(options.simplePre){ + this.parameters.push('hl.simple.pre=' + encodeURIComponent(options.simplePre)); + }else{ + this.parameters.push('hl.simple.pre='); + } + if(options.simplePost){ + this.parameters.push('hl.simple.post=' + encodeURIComponent(options.simplePost)); + }else{ + this.parameters.push('hl.simple.post=<%2Fem>'); + } + if(options.fragmenter){ + this.parameters.push('hl.fragmenter=' + encodeURIComponent(options.fragmenter)); + } + if(options.highlightMultiTerm !== undefined){ + this.parameters.push('hl.highlightMultiTerm=' + encodeURIComponent(options.highlightMultiTerm)); + } + if(options.requireFieldMatch !== undefined){ + this.parameters.push('hl.requireFieldMatch=' + encodeURIComponent(options.requireFieldMatch)); + } + if(options.usePhraseHighlighter !== undefined){ + this.parameters.push('hl.usePhraseHighlighter=' + encodeURIComponent(options.usePhraseHighlighter)); + } + if(options.regexSlop){ + this.parameters.push('hl.regex.slop=' + encodeURIComponent(options.regexSlop)); + } + if(options.regexPattern){ + this.parameters.push('hl.regex.pattern=' + encodeURIComponent(options.regexPattern)); + } + if(options.regexMaxAnalyzedChars){ + this.parameters.push('hl.regex.maxAnalyzedChars=' + encodeURIComponent(options.regexMaxAnalyzedChars)); + } + if(options.preserveMulti !== undefined){ + this.parameters.push('hl.preserveMulti=' + encodeURIComponent(options.preserveMulti)); + } + if(options.payloads !== undefined){ + this.parameters.push('hl.payloads=' + encodeURIComponent(options.payloads)); + } + + return self; +}