I have followed the documentation below to create a smart collection through ElasticSearch:
I was able to create the 2 basic get routes but I am stuck on how to implement the search capability. I have set isSearchable to true in my forest file. How do I modify this route to enable the search function:
The search functionality is the most painful to code. You have to hard code your own way to search your data. In this example you have a simple use case.
Here’s an example that handle search
...
const search = request.query?.search;
// Declare the filters query retrieval first
try {
filters = request.query?.filters && JSON.parse(request.query.filters);
} catch (e) {
filters = undefined;
}
if (search) {
// In case of search you need to handle it
// NOTICE: Create a custom boolean query for Elasticsearch
const booleanQuery = {
should: [{
terms: {
fieldYouNeedToSearchOn: search,
},
}],
minimum_should_match: 1,
};
// NOTICE: Use the elasticsearchHelper to query Elasticsearch
const [results, count] = await Promise.all([
elasticsearchHelper.esSearch(
{ page, pageSize },
booleanQuery,
),
elasticsearchHelper.esCount(booleanQuery),
]);
response.send({
...await serializer.serialize(results),
meta: {
count: count,
}
});
} else {
// The already existing code that retrieve records using filters
const result = await elasticsearchHelper.functionSearch({
page,
pageSize,
filters: filters || undefined,
options,
});
const serializer = new RecordSerializer({ name: 'logs' });
response.send({
...await serializer.serialize(result.results),
meta: {
count: result.count,
}
});
}
} catch (e) {
next(e);
}
In this example you cannot search and filter at the same time. To do so you need to change the search part
// import esTranslateFilter
const { esTranslateFilter } = require('../utils/filter-translator');
...
// AFTER - NOTICE: Create a custom boolean query for Elasticsearch
booleanQuery = { ...booleanQuery, filter: esTranslateFilter(elasticsearchHelper.filterDefinition, filters, options)};
...
This error is specific to Elastocsearch. It’s due to the type of the charge_point_identity in your ES shard. I think you should use a must query with match in this case ?
I let you check the matching you want to implement here: Boolean query | Elasticsearch Guide [7.13] | Elastic
Some example of booleanQuery
// strict matching example
must: {
match: {
charge_point_identity: search,
}
}
// start with example
filter: {
wildcard: {
charge_point_identity: {
value: `${search}*`,
case_insensitive: true,
},
},
}