Search code examples
node.jsmongodbexpressmongoskin

Finding a MongoDB document through a word in a field description in each product with Mongoskin


This is an example of document that I have in my MongoDB:

{
    "_id": ObjectId('5525039895884d66710d0fc3'),
    "prid": "63527",
    "data": {
        "sku": "HF22-81639",
        "name": "Product Test",
        "ean": "8763900872512",
        "description": "This product is my first test",
    }
}

This search for "description" does not work (this is where I need help):

app.get("/description/:id", auth, function(req, res, next) {
    req.collection.findOne({
        "data.description": req.params.id
    }, function(e, result) {
        if(e) return next(e);
        res.send(result);
    });
});

I need to find through a word, all the products that exist in the collection include in the description field that word.


Solution

  • To find through a word, all the products that exist in the collection include in the description field that word, you need a regex match with case insensitivity. You could use the following query (as an example):

    db.product.find({"data.description": /test/i});
    

    where the i in the /test/i indicates case insensitivity, thus the regex matches on the description field for any text with the string "test". The equivalent SQL expression follows:

    select * from product where description like '%test%'
    

    So you could use the same in your route implementation, using the find() method to return all matched documents instead of the findOne() which returns just one document:

    app.get("/description/:id", auth, function(req, res, next) {
        req.collection.find({
            "data.description": /req.params.id/i
        }, function(e, result) {
            if(e) return next(e);
            res.send(result);
        });
    });
    

    Another option is to use the $text operator in your find operation as it performs a text search on the content of the fields indexed with a text index. So the first thing you would do is create a text index on the description field:

    db.collection.createIndex( { "data.description": "text" } )
    

    After that you can query using the $text operator. For example, the following query searches for the term coffee:

    db.collection.find( { $text: { $search: "coffee" } } )
    

    EDIT:

    All things being equal, you can then update your route implementation to use query strings in the URL instead:

    app.get("/description", auth, function(req, res, next) {
        req.collection.find({
            $text: { $search: req.params.q }
        }, function(e, result) {
            if(e) return next(e);
            res.send(result);
        });
    });
    

    which you can query in your browser as http://localhost/description?q=product