I am trying to write an aggregation to regex match a search string across various fields in a list of items. Here is an example JSON array of those items:
{
"user": "String",
"items": [
{
"field1": "String"
"field2": "String"
"field3": 5
"field4": ["String", "String"]
},
{
"field1": "String"
"field2": "String"
"field3": 2
"field4": ["String", "String"]
}
...
]
}
field1 and field 2 are just Strings.
field3 is an integer that references an external mapping like the following (this is just a static map in the code, not another collection):
{
1: "String 1",
2: "String 2",
...
}
field4 is an array of Strings.
What I would like to do is write an aggregation that does a regex match across any/all of these 4 fields and returns all of the items that match any of the fields.
Here's what I have tried so far (query is the string used for the search), and I'm getting pages of 50 at a time via slice:
const [{ items }] = await this.inventoryModel.aggregate([
{ $match: { user }},
{
$project: {
items: {
$slice: [
{
$filter: {
input: '$items',
as: 'item',
cond: {
$or: [
{
$regexMatch: {
input: '$$item.field1',
regex: `(?i)${query}`,
},
},
{
$regexMatch: {
input: '$$item.field2',
regex: `(?i)${query}`,
},
},
],
},
},
},
50,
],
},
_id: 0,
},
},
]);
This is working as intended for a given user with field1 and field2. However, I have not been able to figure out how to apply a regex match to field3 based on the mapping from the value to the external map, or how to apply the regex match to the list of strings in field4. Any help with this would be appreciated as I'm fairly new to Mongo/Mongoose.
I am using Mongoose 7.2.4.
Was able to get the answer from another person:
const branches = Object.entries(field3Mapping).map(([key, value]) => ({
case: { $eq: ["$$item.field3", parseInt(key)] },
then: value,
}));
const [{ items }] = await this.inventoryModel.aggregate([
{ $match: { user } },
{
$project: {
items: {
$slice: [
{
$filter: {
input: '$items',
as: 'item',
cond: {
$or: [
{
$regexMatch: {
input: '$$item.field1',
regex: `(?i)${query}`,
},
},
{
$regexMatch: {
input: '$$item.field2',
regex: `(?i)${query}`,
},
},
{
$regexMatch: {
input: {
$switch: {
branches: branches,
default: "Unknown"
}
},
regex: `(?i)${query}`,
},
},
{
$anyElementTrue: {
$map: {
input: "$$item.field4",
as: "str",
in: {
$regexMatch: {
input: "$$str",
regex: `(?i)${query}`
}
}
}
}
}
],
},
},
},
50,
],
},
_id: 0,
},
},
]);