@@ -147,7 +147,6 @@ export class QuickwitDataSource
147
147
148
148
async importFromAbstractQueries ( abstractQueries : AbstractQuery [ ] ) : Promise < ElasticsearchQuery [ ] > {
149
149
// FIXME: this function does not seem to be used.
150
- console . log ( "importFromAbstractQueries" ) ;
151
150
return abstractQueries . map ( ( abstractQuery ) => this . languageProvider . importFromAbstractQuery ( abstractQuery ) ) ;
152
151
}
153
152
@@ -432,24 +431,23 @@ export class QuickwitDataSource
432
431
const range = options ?. range ;
433
432
const parsedQuery = JSON . parse ( query ) ;
434
433
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
+ // }
440
440
if ( parsedQuery . find === 'terms' ) {
441
441
parsedQuery . field = this . interpolateLuceneQuery ( parsedQuery . field ) ;
442
442
parsedQuery . query = this . interpolateLuceneQuery ( parsedQuery . query ) ;
443
- console . log ( parsedQuery ) ;
444
443
return lastValueFrom ( this . getTerms ( parsedQuery , range ) ) ;
445
444
}
446
445
}
447
-
448
446
return Promise . resolve ( [ ] ) ;
449
447
}
450
448
451
449
interpolateLuceneQuery ( queryString : string , scopedVars ?: ScopedVars ) {
452
- return this . templateSrv . replace ( queryString , scopedVars , 'lucene' ) ;
450
+ return this . templateSrv . replace ( queryString , scopedVars , formatQuery ) ;
453
451
}
454
452
455
453
interpolateVariablesInQueries ( queries : ElasticsearchQuery [ ] , scopedVars : ScopedVars | { } ) : ElasticsearchQuery [ ] {
@@ -695,3 +693,40 @@ function getLogLevelFromKey(dataframe: DataFrame): LogLevel {
695
693
}
696
694
return LogLevel . unknown ;
697
695
}
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