node.js - RegExp in mongodb native

Viewed 39

I'm using node-mongodb-native to implement MongoDB query functions. I need to perform a query if tag matches a part or combined firstName and lastName like this:

filter50WithTagSkip(tag, skip) {
        return new Promise((resolve, reject) => {
            const regex = new RegExp(tag, 'g');
            const or_criteria = [
                { firstName: { $regex: regex, $options: 'i' } },
                { lastName: { $regex: regex, $options: 'i' } },
                { fullName: { $regex: regex, $options: 'i' } },
                { email: { $regex: regex, $options: 'i' } },
                { phone: { $regex: regex, $options: 'i' } }
            ];
            this._db.collection(this._table)
                .aggregate({
                    $project: {
                        deleted: 1,
                        firstName: 1,
                        lastName: 1,
                        email: 1,
                        phone: 1,
                        fullName: { $concat: ['$firstName', ' ', '$lastName'] }
                    }
                }).match({
                    $or: or_criteria,
                    deleted: false
                })
                .skip(skip)
                .limit(50)
                .toArray((err, res) => {
                    if (err) {
                        this._logger.error(err);
                        reject(err);
                    } else {
                        resolve(res);
                    }
                });
        });
    }

With these samples:

{
 firstName: "first1",
 lastName: "last1"
},
{
 firstName: "first2",
 lastName: "last2"
}

If tag is first the result has both documents. But if I comment out firstName and lastName criteria, thinking they are not needed because RegExp will apply pattern on the combined string, the result is an empty array. I feel quite confused

1 Answers

I think I found the solution myself, this is the right way to initialize an aggregate query by this library:

filter50WithTagSkip(tag, skip) {
        return new Promise((resolve, reject) => {
            const regex = new RegExp(tag, 'g');
            const or_criteria = [
                // { firstName: { $regex: regex, $options: 'i' } },
                // { lastName: { $regex: regex, $options: 'i' } },
                { fullName: { $regex: regex, $options: 'i' } },
                { email: { $regex: regex, $options: 'i' } },
                { phone: { $regex: regex, $options: 'i' } }
            ];
            const project_criteria = {
                deleted: 1,
                // firstName: 1,
                // lastName: 1,
                email: 1,
                phone: 1,
                fullName: { $concat: ['$firstName', ' ', '$lastName'] }
            };
            const match_criteria = {
                $or: or_criteria,
                deleted: false
            };
            const aggregate_criteria = [{ $project: project_criteria }, { $match: match_criteria }];
            this._db.collection(this._table)
                .aggregate(aggregate_criteria)
                .skip(skip)
                .limit(50)
                .toArray((err, res) => {
                    if (err) {
                        this._logger.error(err);
                        reject(err);
                    } else {
                        resolve(res);
                    }
                });
        });
    }
Related