I'm currently attempting to implement a multi-field filter on a MongoDB database consisting of issues with multiple fields. I'm learning from the book "Pro MERN Stack" by Vasan Subramanian, but his multi-field filter doesn't include filtering by a String value. I would like my String filter to filter on partial matches, not just exact matches. For example, if a title is "Hello World" I would like a query of "Hello" to match with this title. I've included my functional JS code which currently works only if the title input matches exactly with the title field of an issue in the backend.
I've tried prepending the title with a '/' and appending it with an '/i', and when I print the filter using console.log it outputs { title: '/Hello/i' }. However, if I just hardcode the line and remove the single quotes around the argument to .find() by typing the line as const issues = await db.collection('issues').find({title: /Hello/i }).toArray(); it works on partial matches. Is there some easy way to resolve this issue?
async function list(_, {
status, effortMin, effortMax, title,
}) {
const db = getDb();
const filter = {};
if (status) filter.status = status;
if (title) filter.title = title;
if (effortMin !== undefined || effortMax !== undefined) {
filter.effort = {};
if (effortMin !== undefined) filter.effort.$gte = effortMin;
if (effortMax !== undefined) filter.effort.$lte = effortMax;
}
const issues = await db.collection('issues').find(filter).toArray();
return issues;
}
MongoDB already provides a solution that enables advanced search functionality Atlas Search
The process requires you to create an index for your search queries, such that queries requiring advanced search functionality will have to reference them.
Since you are interested in partially matching fields with in your document, the autocomplete field is what you want to define when creating your index
{
$search: {
"index": "<index name>", // optional, defaults to "default"
"autocomplete": {
"query": "<search-string>",
"path": "<field-to-search>",
"tokenOrder": "any|sequential",
"fuzzy": <options>
}
}
}
Pay attention the the fuzzy object as it allows precise control over how the search is matched.
fuzzy.maxEdits Maximum number of single-character edits required to match the specified search term. Value can be 1 or 2.
fuzzy.prefixLength Number of characters at the beginning of each term in the result that must exactly match.
Having completed creating the index, you are going to need to make queries using the $search aggregation pipeline stage as follows
{
$search: {
"index": "<index-name>",
"autocomplete": {
"query": "<search-string>",
"path": "<field-to-search>"
}
}
}