The search component in 4.34 does not seem to honor exactMatch:False. It will only honor it if the search is in the first characters. Say I am looking for "Driscoll" if I search 'ris' it will not come up, but if I do 'Dri' it will.
In 4.34 the exactMatch: false → prefix only. Where in 4.21 it's like: LIKE '%ris%'
// Wait for your view to be ready
const quickSearch = document.getElementById("quickSearch");
await quickSearch.componentOnReady();
// Assign the map view
quickSearch.view = view;
// Configure only your parcel layer sources
quickSearch.sources = [
{
layer: parcelLayer,
searchFields: ["PartyName_1"],
name: "Search by Owner",
exactMatch: false,
outFields: ["PartyName_1"],
displayField: "PartyName_1",
suggestionsEnabled: true,
},
{
layer: parcelLayer,
searchFields: ["PropertyAddress"],
name: "Search by Address",
outFields: ["PropertyAddress"],
displayField: "PropertyAddress",
exactMatch: false,
},
{
layer: parcelLayer,
searchFields: ["QuickRefID_1"],
name: "Search by Quick Reference ID",
outFields: ["QuickRefID_1"],
displayField: "QuickRefID_1",
exactMatch: false,
}
];
Solved! Go to Solution.
@MatthewDriscoll This is the expected behavior. The change was introduced in 4.25: https://developers.arcgis.com/javascript/latest/4.25/#search-performance-improvements
This AGOL blog also gives additional insights into why this change may have occurred: https://www.esri.com/arcgis-blog/products/arcgis-online/mapping/searching-for-features-in-maps-and-a...
Idea thread found here.
Solution:
// Configure only your parcel layer sources
// Custom getSuggestions bypasses Esri's 5.0 prefix-only behavior
// and restores the old LIKE '%value%' contains search
quickSearch.sources = [
{
layer: parcelLayer,
searchFields: ["PartyName_1"],
displayField: "PartyName_1",
name: "Search by Owner",
outFields: ["PartyName_1"],
exactMatch: false,
suggestionsEnabled: true,
getSuggestions: (params) => {
const query = parcelLayer.createQuery();
query.where = `PartyName_1 LIKE '%${params.suggestTerm.replace(/'/g, "''")}%'`;
query.outFields = ["PartyName_1"];
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = ["PartyName_1"];
query.num = 6;
return parcelLayer.queryFeatures(query).then(results => {
return results.features.map(f => ({
key: f.attributes.PartyName_1,
text: f.attributes.PartyName_1,
sourceIndex: params.sourceIndex
}));
});
}
},
{
layer: parcelLayer,
searchFields: ["PropertyAddress"],
displayField: "PropertyAddress",
name: "Search by Address",
outFields: ["PropertyAddress"],
exactMatch: false,
suggestionsEnabled: true,
getSuggestions: (params) => {
const query = parcelLayer.createQuery();
query.where = `PropertyAddress LIKE '%${params.suggestTerm.replace(/'/g, "''")}%'`;
query.outFields = ["PropertyAddress"];
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = ["PropertyAddress"];
query.num = 6;
return parcelLayer.queryFeatures(query).then(results => {
return results.features.map(f => ({
key: f.attributes.PropertyAddress,
text: f.attributes.PropertyAddress,
sourceIndex: params.sourceIndex
}));
});
}
},
{
layer: parcelLayer,
searchFields: ["QuickRefID_1"],
displayField: "QuickRefID_1",
name: "Search by Quick Reference ID",
outFields: ["QuickRefID_1"],
exactMatch: false,
suggestionsEnabled: true,
getSuggestions: (params) => {
const query = parcelLayer.createQuery();
query.where = `QuickRefID_1 LIKE '%${params.suggestTerm.replace(/'/g, "''")}%'`;
query.outFields = ["QuickRefID_1"];
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = ["QuickRefID_1"];
query.num = 6;
return parcelLayer.queryFeatures(query).then(results => {
return results.features.map(f => ({
key: f.attributes.QuickRefID_1,
text: f.attributes.QuickRefID_1,
sourceIndex: params.sourceIndex
}));
});
}
}
];
Following this. Not sure if this is related, but we have noticed few differences as well. It seems that Search in ExP works differently to Search in Map SDK. For example, when I search "Nora", below are the results I have obtained from Search widget in Map SDK and Search widget from ExP Builder.
Search result for "Nora" in Map SDK Search widget - https://imgur.com/a/XWumpC0
Search result for "Nora" in ExP Search widget - https://imgur.com/a/sPxLVy6
The results seem different regardless of the setting. In the ExP builder, we can see the results include the search term being in the middle of the result whereas in the Map SDK version, it always displays the start's with results.
@MatthewDriscoll This is the expected behavior. The change was introduced in 4.25: https://developers.arcgis.com/javascript/latest/4.25/#search-performance-improvements
This AGOL blog also gives additional insights into why this change may have occurred: https://www.esri.com/arcgis-blog/products/arcgis-online/mapping/searching-for-features-in-maps-and-a...
Is there a known fix or do I go create my own? Seems like it makes this component pretty useless for anything other then location. @NZGIS this is directly related to your problem, it is prefix only now.
I am not aware of any ways to adjust this through the API. However, adding "%" to the front of your search term should do the trick.
@NZGIS , This feature exists in ExB's Search Widget, but only as a search result rather than a search suggestion. Let me know if there are any questions on this.
Idea thread found here.
Solution:
// Configure only your parcel layer sources
// Custom getSuggestions bypasses Esri's 5.0 prefix-only behavior
// and restores the old LIKE '%value%' contains search
quickSearch.sources = [
{
layer: parcelLayer,
searchFields: ["PartyName_1"],
displayField: "PartyName_1",
name: "Search by Owner",
outFields: ["PartyName_1"],
exactMatch: false,
suggestionsEnabled: true,
getSuggestions: (params) => {
const query = parcelLayer.createQuery();
query.where = `PartyName_1 LIKE '%${params.suggestTerm.replace(/'/g, "''")}%'`;
query.outFields = ["PartyName_1"];
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = ["PartyName_1"];
query.num = 6;
return parcelLayer.queryFeatures(query).then(results => {
return results.features.map(f => ({
key: f.attributes.PartyName_1,
text: f.attributes.PartyName_1,
sourceIndex: params.sourceIndex
}));
});
}
},
{
layer: parcelLayer,
searchFields: ["PropertyAddress"],
displayField: "PropertyAddress",
name: "Search by Address",
outFields: ["PropertyAddress"],
exactMatch: false,
suggestionsEnabled: true,
getSuggestions: (params) => {
const query = parcelLayer.createQuery();
query.where = `PropertyAddress LIKE '%${params.suggestTerm.replace(/'/g, "''")}%'`;
query.outFields = ["PropertyAddress"];
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = ["PropertyAddress"];
query.num = 6;
return parcelLayer.queryFeatures(query).then(results => {
return results.features.map(f => ({
key: f.attributes.PropertyAddress,
text: f.attributes.PropertyAddress,
sourceIndex: params.sourceIndex
}));
});
}
},
{
layer: parcelLayer,
searchFields: ["QuickRefID_1"],
displayField: "QuickRefID_1",
name: "Search by Quick Reference ID",
outFields: ["QuickRefID_1"],
exactMatch: false,
suggestionsEnabled: true,
getSuggestions: (params) => {
const query = parcelLayer.createQuery();
query.where = `QuickRefID_1 LIKE '%${params.suggestTerm.replace(/'/g, "''")}%'`;
query.outFields = ["QuickRefID_1"];
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = ["QuickRefID_1"];
query.num = 6;
return parcelLayer.queryFeatures(query).then(results => {
return results.features.map(f => ({
key: f.attributes.QuickRefID_1,
text: f.attributes.QuickRefID_1,
sourceIndex: params.sourceIndex
}));
});
}
}
];
this works very well.
Instead of using hard coded num 6 I guess you can read the effective maxSuggestions from the params.
query.num = params.maxSuggestions;
We also am using multiple fields as search fields I need to map them for the whereclause.
Additionally I put them as outFields and orderByFields.
Here is my code:
/**
* Creates a suggestion callback that restores contains-style matching for all configured search fields.
* @Param layer Feature layer queried for suggestions
* @Param searchFields Fields that are searched using LIKE '%term%'
* @Param displayField Preferred field used for sorting and suggestion display
*/
private createContainsSuggestions(
layer: FeatureLayer,
searchFields: string[],
displayField?: string | null
): NonNullable<LayerSearchSourceProperties['getSuggestions']> {
return async (params) => {
const suggestTerm = params.suggestTerm?.trim();
if (!suggestTerm) {
return [];
}
const escapedTerm = this.escapeSqlStringLiteral(suggestTerm);
const query = layer.createQuery();
query.where = searchFields
.map(searchField => `${searchField} LIKE '%${escapedTerm}%'`)
.join(' OR ');
query.outFields = searchFields;
query.returnGeometry = false;
query.returnDistinctValues = true;
query.orderByFields = searchFields;
if (typeof params.maxSuggestions === 'number') {
query.num = params.maxSuggestions;
}
const result = await layer.queryFeatures(query);
return result.features.flatMap(feature => {
const textValue = displayField ? feature.attributes?.[displayField] : undefined;
if (!textValue) {
return [];
}
return [{
key: textValue,
text: textValue,
sourceIndex: params.sourceIndex
}];
});
};
}
/**
* Escapes single quotes for safe use in SQL string literals.
* @Param value Raw user-provided search value
*/
private escapeSqlStringLiteral(value: string): string {
return value.replace(/'/g, "''");
}