@@ -147,7 +147,6 @@ export class QuickwitDataSource
147147
148148 async importFromAbstractQueries ( abstractQueries : AbstractQuery [ ] ) : Promise < ElasticsearchQuery [ ] > {
149149 // FIXME: this function does not seem to be used.
150- console . log ( "importFromAbstractQueries" ) ;
151150 return abstractQueries . map ( ( abstractQuery ) => this . languageProvider . importFromAbstractQuery ( abstractQuery ) ) ;
152151 }
153152
@@ -432,24 +431,23 @@ export class QuickwitDataSource
432431 const range = options ?. range ;
433432 const parsedQuery = JSON . parse ( query ) ;
434433 if ( query ) {
435- if ( parsedQuery . find === 'fields' ) {
436- parsedQuery . type = this . interpolateLuceneQuery ( parsedQuery . type ) ;
437- return lastValueFrom ( this . getFields ( parsedQuery . type , range ) ) ;
438- }
439-
434+ // Interpolation of variables with a list of values for which we don't
435+ // know the field name is not supported yet.
436+ // if (parsedQuery.find === 'fields') {
437+ // parsedQuery.type = this.interpolateLuceneQuery(parsedQuery.type);
438+ // return lastValueFrom(this.getFields(parsedQuery.type, range));
439+ // }
440440 if ( parsedQuery . find === 'terms' ) {
441441 parsedQuery . field = this . interpolateLuceneQuery ( parsedQuery . field ) ;
442442 parsedQuery . query = this . interpolateLuceneQuery ( parsedQuery . query ) ;
443- console . log ( parsedQuery ) ;
444443 return lastValueFrom ( this . getTerms ( parsedQuery , range ) ) ;
445444 }
446445 }
447-
448446 return Promise . resolve ( [ ] ) ;
449447 }
450448
451449 interpolateLuceneQuery ( queryString : string , scopedVars ?: ScopedVars ) {
452- return this . templateSrv . replace ( queryString , scopedVars , 'lucene' ) ;
450+ return this . templateSrv . replace ( queryString , scopedVars , formatQuery ) ;
453451 }
454452
455453 interpolateVariablesInQueries ( queries : ElasticsearchQuery [ ] , scopedVars : ScopedVars | { } ) : ElasticsearchQuery [ ] {
@@ -695,3 +693,40 @@ function getLogLevelFromKey(dataframe: DataFrame): LogLevel {
695693 }
696694 return LogLevel . unknown ;
697695}
696+
697+ function formatQuery ( value : string | string [ ] , variable : any ) : string {
698+ if ( typeof value === 'string' ) {
699+ return luceneEscape ( value ) ;
700+ }
701+ if ( Array . isArray ( value ) ) {
702+ if ( value . length === 0 ) {
703+ return '__empty__' ;
704+ }
705+ const fieldName = JSON . parse ( variable . query ) . field ;
706+ const quotedValues = value . map ( ( val ) => '"' + luceneEscape ( val ) + '"' ) ;
707+ // Quickwit query language does not support fieldName:(value1 OR value2 OR....)
708+ // like lucene does.
709+ // When we know the fieldName, we can directly generate a query
710+ // fieldName:value1 OR fieldName:value2 OR ...
711+ // But when we don't know the fieldName, the simplest is to generate a query
712+ // with the IN operator. Unfortunately, IN operator does not work on JSON field.
713+ // TODO: fix that by using doing a regex on queryString to find the fieldName.
714+ // Note that variable.id gives the name of the template variable to interpolate,
715+ // so if we have `fieldName:${variable.id}` in the queryString, we can isolate
716+ // the fieldName.
717+ if ( typeof fieldName !== 'string' ) {
718+ return 'IN [' + quotedValues . join ( ' ' ) + ']' ;
719+ }
720+ return quotedValues . join ( ' OR ' + fieldName + ':' ) ;
721+ } else {
722+ return luceneEscape ( `${ value } ` ) ;
723+ }
724+ }
725+
726+ function luceneEscape ( value : string ) {
727+ if ( isNaN ( + value ) === false ) {
728+ return value ;
729+ }
730+
731+ return value . replace ( / ( [ \! \* \+ \- \= < > \s \& \| \( \) \[ \] \{ \} \^ \~ \? \: \\ / " ] ) / g, '\\$1' ) ;
732+ }
0 commit comments