B K
B K

Reputation: 359

How do you pass multiple parameters from the client through NodeJS to MongoDB?

Scenario: I want to have a searchbox that takes well-formed MongoDB db.collection.find() parameters in the same form as the MongoDB console, and will display the result on the webpage.

I have already the logic that works when it comes to a parameter, that I know. Eg. getting document by ID:

var query = {};
var selector = "id";
query[selector] = Number(id);
collection.find(
    query, {},
    function(e, docs) {
        if (e) { ... }
        if (docs != null && docs.length != 0) {
            res.json(docs);
        } else { ... }
    });

However, what to do if I want to have multiple parameters that I don't know beforehand on the bakcend?

What to look out for when sending the client GET request?

Thanks.

EDIT:

Perhaps a better way to explain the searchbox functionality would be to compare it to the formula editor in Excel. I would like to be able to insert 'search formulas' and get the data results.

EDIT2:

I am using Express for the project.

Searchbox value that should work:

{"pocet_nabidek":2}

This is the approach I took, based on @x_maras suggestions:

Client side

// send AJAX request when the search field changes
$('#searchField').keyup(function() {
    clearTimeout(timer);
    var timer = setTimeout(function() {

            //call your function here
            q = $('#searchField').val();
            if (q.length != 0 && q != undefined) {

                var payload = "/api/zakazka?q="+replaceURLParam(q);
                $.getJSON(payload, function(data){

                    console.log(data);

                });

            }

        }, 500) // delay
});

Server side

var express = require('express');
var router = express.Router();

// ... more code ...

router.get('/zakazka', function(req, res) {

    var pagesize = req.query["pagesize"];
    var offset = req.query["offset"];
    var q = req.query["q"];

    if (q != undefined || q != null) {

        console.log("got a query passed on!");
        q = decodeURI(q);
        q = JSON.parse(q);
        return
    } 

    var collection = req.db.get('zakazky');

    collection.find(q, {
        limit: pagesize,
        skip: offset
    }, function(e, docs) {
        if (e) {
            console.log(`Error: X doesn't seem to exist`);
        }
        if (docs != null && docs.length != 0) {
            res.json(docs);
        } else {
            res.writeHead(404, {
                "Content-type": "text/plain"
            });
            res.end(`Error: X doesn't seem to exist`);
        }
    });

});

If I modify the code as per below, the query works

// This actually works: 
// var q = {};
// var selector = "pocet_nabidek";
// q[selector] = Number(2);

This is a sample of a document we're querying

{
    "_id": ObjectId("568d91396912101c1007ab4e"),
    "cena": 1636363,
    "cena_celkem": 1500000,
    "cena_dopocitano": false,
    "created": "2015-04-07T13:45:10.420739",
    "datum_zadani": "2015-02-16",
    "dodavatel": "/api/v1/dodavatel/381836/",
    "druh_rizeni": "/api/v1/druh_rizeni/1116/",
    "id": 1312587,
    "modified": "2015-04-18T14:22:10.765733",
    "nazev": "Pohostinství",
    "pocet_nabidek": 2,
    "podporeno_eu": true,
    "popis": "Kurzy v oblasti pohostinství (formou profesní kvalifikace)",
    "ramcova_smlouva": true,
    "resource_uri": "/api/v1/zakazka/1312587/",
    "skupina": "490648-ISVZUS_2011",
    "typ_zakazky": "/api/v1/typ_zakazky/193/",
    "zadavatel": "/api/v1/zadavatel/131528/",
    "zdroj": "http://www.vestnikverejnychzakazek.cz/en/Form/Display/568547",
    "zdroj_nazev": "isvzus.cz",
    "cpv": ["80000000-4", "80400000-8", "", "", ""],
    "predpokladana_hodnota": "1 500 000,00"
}

Upvotes: 0

Views: 4198

Answers (1)

x_maras
x_maras

Reputation: 2217

Let's assume that you are making the following GET request

GET /v1/myendpoint?key1=value1&key2=value2

You could create a javascript object from the querystring like the following

{key1: 'value1', key2: 'value2'}

and use it in a mongo query

var cursor = collection.find({key1: 'value1', key2: 'value2'})

Updated solution based on the server side snippet

var express = require('express');
var router = express.Router();

// ... more code ...

router.get('/zakazka', function(req, res, next) {
    var query = req.query;
    var q = query.q;

    if (q) {
        console.log('got a query passed on!');
        q = decodeURI(q);
        q = JSON.parse(q);
        // You don't need a return here
    }

    req.db.collection('zakazky').find(q, {
        limit: query.pagesize,
        skip: query.offset
    }, function (err, docs) {
        if (err) {
            console.log('Error: ', err);
            /**
             * It would be good to use next here with a generic error handler middleware:
             * However, you don't have the error handling middleware and the following code it
             * won't work for you, therefore it is commented.
             *
             * var dbError = new Error('Database Error');
             * dbError.status = 500;
             * dbError.details = err;
             * return next(dbError);
             */
        }

        if (docs && docs.length !== 0) {
            return res.status(200).json(docs);
        }

        /**
         * You could use next here and pass the error to a generic error handler.
         * However, you don't have the error handling middleware and the following code it
         * won't work for you, therefore it is commented.
         *
         * var reqError = new Error('Error: X doesn\'t seem to exist');
         * reqError.status = 404;
         * next(reqError);
         */
        res.status(404).send('Error: X doesn\'t seem to exist');
    });

});

Upvotes: 1

Related Questions