Dipta Biswas
Dipta Biswas

Reputation: 11

Can I use $match to match a data based on whether it empty or not In MongoDb

Like in my case I wanted to match the filter based on its value. if the filter value is empty I want to skip that field to match. is that possible in the same query?

Can I $match data based on whether it empty or not. In MongoDB

Getting following error:

ERROR - Cast to boolean failed for value "" at path "undefined"
      at castBoolean (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\cast\boolean.js:28:9)
      at SchemaBoolean.cast (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\schema\boolean.js:195:12)
      at SchemaBoolean.SchemaType.applySetters (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\schematype.js:1075:12)
      at SchemaBoolean.SchemaType._castForQuery (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\schematype.js:1510:15)
      at SchemaBoolean.castForQuery (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\schema\boolean.js:224:15)
      at SchemaBoolean.SchemaType.castForQueryWrapper (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\schematype.js:1477:20)
      at cast (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\cast.js:331:32)
      at cast (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\cast.js:74:18)
      at model.Query.Query.cast (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\query.js:4772:12)
      at model.Query.<anonymous> (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\query.js:2267:10)
      at model.Query._wrappedThunk [as _countDocuments] (D:\js\Anoko\anoko-backend\node_modules\mongoose\lib\helpers\query\wrapThunk.js:16:8)
      at D:\js\Anoko\anoko-backend\node_modules\kareem\index.js:369:33
      at processTicksAndRejections (internal/process/task_queues.js:79:11) {
    stringValue: '""',
    messageFormat: undefined,
    kind: 'boolean',
    value: '',
    path: undefined,
    reason: undefined
  }

code:

const page = parseInt(req.query.page);
const limit = parseInt(req.query.limit);

const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const q = req.query.q;

const filter = req.query.filter === "true" ? true : !req.query.filter ? "" : false;
console.log("Search query", filter);

User.aggregate([{
    $match: {
        $and: [
            {
                $or: [
                    { email: { $regex: new RegExp("^" + q.toLowerCase(), "i") } },
                    { firstName: { $regex: new RegExp("^" + q.toLowerCase(), "i") } },
                ],
            },
            {
                block: !filter ? null : filter,
            },
        ],
    },
}, {
    $lookup: {
        from: "userdetails",
        localField: "_id",
        foreignField: "user",
        as: "details",
    },
}, {
    $lookup: {
        from: "userbios",
        localField: "_id",
        foreignField: "user",
        as: "bios",
    },
}, {
    $lookup: {
        from: "usersettings",
        let: { userID: "$_id" },
        pipeline: [
            {
                $match: {
                    $expr: {
                        $and: [
                            {
                                $eq: ["$user", "$$userID"],
                            },
                        ],
                    },
                },
            },
            { $project: { finalConnection: 1, matches: 1 } },
        ],
        as: "userInfo",
    },
}, { $project: { password: 0, _v: 0, createdAt: 0 } },
])
    .skip(startIndex)
    .limit(limit)

Upvotes: 0

Views: 33

Answers (1)

adeel
adeel

Reputation: 361

Create your where condition before query like,

where = {};

Create check something like this as per your requirement,

  if (filter) {
    where.block = filter
  }

Exclude null check and pass the only necessary where condition to match stage. In this way, you can avoid some extra matches in the query.

Upvotes: 1

Related Questions