Mongo Case Insensitive InList Query

23 / Jul / 2016 by Sandeep Poonia 0 comments

As we know in Mongo the match queries are case sensitive. So whether we do a find() operation or use $match stage of aggregate pipeline, the condition would be true only if its a exact case sensitive match. Of cource we can use regex to do case insensitive queries but then again it will not work when we are trying to find a match with in a list of possible matches. Although we can use javascript for that but there is no easy way when you want to do this using java driver for mongo and aggregation pipeline.

To understand the requirement, lets see below json document list from a Sales collection:

{
    "_id" : ObjectId("576105331d41b83a770253f2"),
    "EndUser" : "XYZ Ltd",
    "SoldTo" : "0001005191",
    "SalesItemQuantity" : NumberInt(10),
    "VendorName" : "ABC",
    "SalesOrder" : "SO411187"
}
{
    "_id" : ObjectId("576105331d41b83a770253f3"),
    "EndUser" : "XYZ LTD",
    "SoldTo" : "0001005191",
    "SalesItemQuantity" : NumberInt(8),
    "VendorName" : "abc",
    "SalesOrder" : "SO417994"
}
{
    "_id" : ObjectId("576105331d41b83a770253f4"),
    "EndUser" : "AAA LTD",
    "SoldTo" : "0001005191",
    "SalesItemQuantity" : NumberInt(13),
    "VendorName" : "XYZ",
    "SalesOrder" : "SO417564"
}

We have three documents here. We want to find all the documents where EndUser value is in list [XYZ LTD, ABC LTD]. We can say “XYZ Ltd” and “XYZ LTD” are same for us but when we query to mongo, they are different.

So how to do this:
We need to use an aggregate pipeline here instead of a direct find() operation. Stages of pipeline query:

  1. Projection – During this stage we will convert all EndUser values to their upper case.
  2. Match – Match upper case EndUser values with the given list of values.

Mongo Query:

db.Sales.aggregate(

  // Pipeline
  [
    // Stage 1
    {
      $project: {
        //Convert EndUser to UpperCase
        "EndUser": {
          "$let": {
            //var declaration
            "vars": {
              "endUserVar": "$EndUser"
            },
            "in": {
              //conversion to upper case
              "$toUpper": "$$endUserVar"
            }
          }
        },
        //We need to include all other fields also in projection otherwise they will not be available in next stage ε(´סּ︵סּ`)з
        "SoldTo": 1,
        "SalesOrder": 1,
        "VendorName": 1,
        "SalesItemQuantity": 1
      }
    },

    // Stage 2: match using in operator
    {
      $match: {
        "EndUser" : {
          "$in" : [
          	"XYZ LTD",
          	"ABC LTD"
          ]
        }
      }
    }

  ]

);

One issue that I can see here is during projection query at first stage, we have to include all parent keys which we want to be available in next stage. But again if it helps to resolve our problem then we can do that ;-)

FOUND THIS USEFUL? SHARE IT

Leave a comment -