Home > front end >  MongoDB match expression query not working
MongoDB match expression query not working

Time:04-22

MongoDb query match expression not working.

I have a posts collection and want to return only those posts which match the user Id of the user who created it but my query does not seem to be working.

Sample Dataset

[
  // 1
  {
    "_id": ObjectId("6257047cffd61ab62864c1ae"),
    "type": "A",
    "source": "B",
    "status": "A",
    "user": ObjectId("622b55ff0b0af6b049c387d3")
  },
  // 2
  {
    "_id": ObjectId("6257047cffd61ab62864c1ad"),
    "type": "B",
    "source": "A",
    "status": "A",
    "user": ObjectId("622b55ff0b0af6b049c387d3")
  },
  // 3
  {
    "_id": ObjectId("6257047cffd61ab62864c1ce"),
    "type": "A",
    "source": "C",
    "status": "B",
    "user": ObjectId("622b55ff0b0af6b049c387d3")
  },
  // 4
  {"_id": ObjectId("6257047cffd61ab62864c1cb"),
  "type": "A",
  "source": "B",
  "status": "C",
  "user": ObjectId("622b56250b0af6b049c387d6")
}
]

MongoDb Query:-

db.collection.aggregate([
  {
    $addFields: {
      paramType: "All",
      paramSource: "All",
      paramStatus: "All",
      
    },
    
  },
  {
    $match: {
      $expr: {
        $and: [
          {
            user: ObjectId("622b55ff0b0af6b049c387d3")
          },
          {
            $or: [
              {
                $eq: [
                  "$paramType",
                  "All"
                ],
                
              },
              {
                $eq: [
                  "$paramType",
                  "$type"
                ],
                
              },
              
            ],
            
          },
          {
            $or: [
              {
                $eq: [
                  "$paramSource",
                  "All"
                ],
                
              },
              {
                $eq: [
                  "$paramSource",
                  "$source"
                ],
                
              },
              
            ],
            
          },
          {
            $or: [
              {
                $eq: [
                  "$paramStatus",
                  "All"
                ],
                
              },
              {
                $eq: [
                  "$paramStatus",
                  "$status"
                ],
                
              },
              
            ],
            
          },
          
        ],
        
      },
      
    },
    
  },
  {
    $setWindowFields: {
      output: {
        totalCount: {
          $count: {}
        }
      }
    }
  },
  {
    $sort: {
      createdAt: -1
    }
  },
  {
    $skip: 0
  },
  {
    $limit: 6
  },
  {
    "$project": {
      "paramSource": false,
      "paramStatus": false,
      "paramType": false,
      
    }
  }
])

Query Output:-

[
  {
    "_id": ObjectId("6257047cffd61ab62864c1ae"),
    "source": "B",
    "status": "A",
    "totalCount": 4,
    "type": "A",
    "user": ObjectId("622b55ff0b0af6b049c387d3")
  },
  {
    "_id": ObjectId("6257047cffd61ab62864c1ad"),
    "source": "A",
    "status": "A",
    "totalCount": 4,
    "type": "B",
    "user": ObjectId("622b55ff0b0af6b049c387d3")
  },
  {
    "_id": ObjectId("6257047cffd61ab62864c1ce"),
    "source": "C",
    "status": "B",
    "totalCount": 4,
    "type": "A",
    "user": ObjectId("622b55ff0b0af6b049c387d3")
  },
  {
    "_id": ObjectId("6257047cffd61ab62864c1cb"),
    "source": "B",
    "status": "C",
    "totalCount": 4,
    "type": "A",
    "user": ObjectId("622b56250b0af6b049c387d6")
  }
]

The query does not work output contains posts created by all users it is not filtering.

CodePudding user response:

The $match part should look like this:

  {
    $match: {
      $and: [
        {
          user: ObjectId("622b55ff0b0af6b049c387d3")
        },
        {
          $or: [{paramType: {$eq: "All"}},
            {$expr: {$eq: ["$paramType", "$type"]}}
          ]
        },
        {
          $or: [{paramSource: {$eq: "All"}},
            {$expr: {$eq: ["$paramSource", "$type"]}}
          ]
        },
        {
          $or: [{paramStatus: {$eq: "All"}},
            {$expr: {$eq: ["$paramStatus", "$type"]}}
          ]
        }
      ]
    }
  }

The $expr should only be assigned to cases where both values are in the document. This query returns 3 / 4 documents, the ones in which user: ObjectId("622b55ff0b0af6b049c387d3")

BTW, the last 3 conditions on this $match stage are redundant, as they will always be true, since the query sets them with the value 'All' on the former stage

  • Related