How to achieve relavent search in mongodb with partial text matching

68 views Asked by At

Suppose I have a list of products in my mongodb collection named products, with the following test data as follows

Samsung Mobile Phone

Samsung Fridge

Samsung Washing Machiene

I Could active relavant search by using the following mongo aggregate query

db.products.aggregate(
    [{
        "$match": {
            "$and": [{
                "status": "active"
            }, {
                "delete": false
            },  { 
                "$text": { $search: "Samsung Mobile" } 
            }]
        }
    },
    { $sort: { score: { $meta: "textScore" } } }
    ]
);

The problem is that I could not get result with partial keyword for example "Samsun" . This will give empty result for me , full aggregate query with empty result is given below

db.products.aggregate(
    [{
        "$match": {
            "$and": [{
                "status": "active"
            }, {
                "delete": false
            },  { 
                "$text": { $search: "Samsun" } 
            }]
        }
    },
    { $sort: { score: { $meta: "textScore" } } }
    ]
);
1

There are 1 answers

2
jQueeny On

Using $text to search on things like a product name is overkill given that product names will only be a few words at most. In mongodb $text is best for things like a product description or specifications so that your users can search for keywords that might appear in a short paragraph about the product or a review etc. For things like product name I would recommenced a simple $regex to look for a partial match despite the fact you won't get a textScore value like so:

db.products.aggregate([
  {
    "$match": {
      "status": "active",
      "delete": false,
      "name": {
        $regex: "Samsun",
        $options: "i"
      }
    }
  }
])

Or if you don't intend on doing further aggregate stages then a simple find will do the job like so:

db.products.find({
  "status": "active",
  "delete": false,
  "name": {
    $regex: "Samsun",
    $options: "i"
  }
})

If you are using Atlas then you can do a partial match with wildcard or autocomplete. The excellent How to Run Partial Match Atlas Search Queries resource has a few Node code samples that explain it pretty well but will require a little bit of preconfiguration.