Search Widget 4.25 - 'Deep' searching feature layer attributes?

888
3
11-22-2022 12:56 PM
MichaelSnook
Occasional Contributor III

Hello Javascripters,

I'm having a slight issue with the newest JSAPI (4.25) search widget and wondering if I'm missing something.  The 'what's new' documentation says that:

In order to make the Search widget faster and more efficient with a layer-based source, we removed the leading wildcard in layer-based source searches...

This is causing issues with searching beyond the first word in an attribute column.  For example, I have a sentence stored in a column that I'm searching on...'The Elk Horn Lodge...' is how it begins.  Can cannot get results for anything but 'The' in the search box.  There doesn't seem to be anything obvious to undo this new 'enhancement'.

In 4.24, searches for 'Elk', 'Lodge' or anything else that was in the attributes worked fine.

Any help would be great.

Thanks!

3 Replies
JoelBennett
MVP Regular Contributor

This is my least favorite change with 4.25 thus far.  The Search widget has used "contains" logic for many years, and to suddenly change it up to "starts with" logic without some kind of means by which we can turn it on or off (like a configuration parameter or something) is a bit of a curveball out of nowhere.

Anyhow, the heart of the workaround I've devised for 4.25 intercepts the process where the associated layer's queryFeatures function is called, and "fixes" the where clause.  It looks something like this:

var source = new LayerSearchSource(options);
source.layer.defaultQueryFeatures = source.layer.queryFeatures;
source.layer.queryFeatures = function(query) {
	if ((query) && (typeof query.where == "string"))
		query.where = query.where.replace(/ LIKE '/g, " LIKE '%");

	return this.defaultQueryFeatures.apply(this, arguments);
};

 

Note that "LayerSearchSource" is esri/widgets/Search/LayerSearchSource.  Note also that there are some unlikely cases where this could cause unintended side effects, because any time the layer's queryFeatures function is called, any instances of " LIKE '" in the query's where property will be changed to " LIKE '%"...so you might consider how the layer object is being used, and if other functionality executes LIKE-based queries.

 

My workaround for 3.42 is "somewhat" cleaner in that the where clause is only altered for queries executed by the widget itself:

var search = new Search(options, srcNode);
search._defaultWhereClause = search._whereClause;
search._whereClause = function() {
	var wc = this._defaultWhereClause.apply(this, arguments);

	return ((typeof wc == "string") ? wc.replace(/ LIKE '/g, " LIKE '%") : wc);
};

 

0 Kudos
MichaelSnook
Occasional Contributor III

Thanks Joel...this will definitely give me a start on duct-taping the widget!

Mike

0 Kudos
GreggRoemhildt2
New Contributor III

@MichaelSnook  here's another alternative approach I found with the 4.x api - it basically uses the esri request interceptors to intercept matching /query:

 

const log = debug('interceptors');

// fix the search query issue
esriConfig.request.interceptors.push({
    urls: /\/query/,
    before({ requestOptions }) {
        if (/LIKE '[^%]/g.test(requestOptions.query?.where)) {
            log('like request intercepted', requestOptions);
            requestOptions.query.where = requestOptions.query.where.replace(/ LIKE \'/g, ' LIKE \'%');
        }
    }
})