Search code examples
mongodbaggregation-frameworkspring-data-mongodbnosql-aggregation

How to perform a $match with $or inside $switch statement in Mongo


Hi I am trying to get multiple searches inside switch so i want to do if one of the following user:search_data||com:search_data||fruit:serch_data matches return search results. i want to do,

$match:{
          $or:[{ user:{$regex:"search_data"}},
          {com:{$regex:"search_data"}},
          {fruit:{$elemMatch: {name:{$regex:"search_data"}}}}
}

this is a search if user it should search user, if com it should search company I have able to do that now i want when we gives all if search data exits on user OR Com OR fruit it should return the search results

   {
            $match: {
              $expr: {
                $switch: {
                  branches: [
                    {
                      case: {
                        $eq: ['$search', 'all']
                      },
                      then: {
                       
                       //to this
                      }
                    },
                 ],
                 default: {}
              }
            }
          }

sample data

 user:"rithuwa",
  com:"abc",
  fruit:[{name:"mango",des:"aaaaa"},{name:"mango",des:"nnnn"}]

sample input

search_data:"rit"---->since this is in user it should output the record
search_data:"mango"--->since it in the fruit.name it should output the record
search_data:"ab"---->since it in the com it should output the record
search_data:"me"---->since it not in user,com or fruit should not give search record  

Solution

  • Query

    • if type is all check the regex in all
    • else check in each based on type

    *you know the type before sending the query, so you can do this switch case on application code, and have 4 queries, so based on the type to send one of them (the bellow does this on the server and query is bigger, you can do it with 4 much smaller queries)

    Playmongo

    aggregate(
    [{"$set": {"searchData": "mango", "searchType": "tags"}},
     {"$match": 
       {"$expr": 
         {"$switch": 
           {"branches": 
             [{"case": {"$eq": ["$searchType", "all"]},
                "then": 
                 {"$or": 
                   [{"$regexMatch": {"input": "$name", "regex": "$searchData"}},
                     {"$regexMatch": {"input": "$company", "regex": "$searchData"}},
                     {"$reduce": 
                       {"input": "$tags",
                        "initialValue": false,
                        "in": 
                         {"$or": 
                           ["$$value",
                             {"$regexMatch": 
                               {"input": "$$this.name", "regex": "$searchData"}}]}}}]}},
               {"case": {"$eq": ["$searchType", "name"]},
                "then": 
                 {"$regexMatch": {"input": "$name", "regex": "$searchData"}}},
               {"case": {"$eq": ["$searchType", "company"]},
                "then": 
                 {"$regexMatch": {"input": "$company", "regex": "$searchData"}}},
               {"case": {"$eq": ["$searchType", "tags"]},
                "then": 
                 {"$reduce": 
                   {"input": "$tags",
                    "initialValue": false,
                    "in": 
                     {"$or": 
                       ["$$value",
                         {"$regexMatch": 
                           {"input": "$$this.name", "regex": "$searchData"}}]}}}}],
            "default": true}}}},
         {"$unset": ["searchData", "searchType"]}])