Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly instantiate a Waterline Model Object from a sails-mongo native result?

I am using SailsJS on a project and I need to use native() for certain querys. The problem I have is that I can't find a proper way to instantiate a Waterline Model Object from the mongo collection find result. I have being searching information about this and the only thing I have found is the following:

var instance = new Model._model(mongo_result_item);

This should work properly, but when I do instance.save(function(err, ins){}); the model throws an error because of the "_id" field, that should be "id".

I have took a look into sails-mongo code and I found that for the "find" method they do this:

// Run Normal Query on collection
collection.find(where, query.select, queryOptions).toArray(function(err, docs) {
    if(err) return cb(err);
    cb(null, utils.normalizeResults(docs, self.schema));
});

So the normalizeResults does the magic with the "_id" attribute, and other stuff.

The way I am doing this right now is to require the sails-mongo utils.js file to have access to this method.

Full sample:

var mongoUtils = require('sails-mongo/lib/utils.js');

SampleModel.native(function(nativeErr, collection){

    collection.find({ 'field' : value }).toArray(function(collectionErr, results){
        if (!results || results.length == 0) return res.restfullInvalidFieldValue({ msg : 'INVALID_VALUE' });

        var norm_results = mongoUtils.normalizeResults(results);
        var instance = new SampleModel._model(norm_results[0]);

    });

});

Is there a better / proper way to achieve this ?

I need to do a native search because I have found a problem with Waterline find() method using strings, where the search should be case sensitive. Every string field on the model is being used as a regular expression match of the form : /^{string}$/i

Searching by a regular expression with the case insensitive flag will give me problems. In the other hand, doing { field : { $regex : new RegExp('^'+regexp_escaped_string+'$') } } could be possible, but I think it will perform worst than { field : value }.

If someone have found a different workaround for the case insensitive problem, please, point me in the right direction.

Thanks in advance.

like image 424
agsv Avatar asked Oct 14 '15 10:10

agsv


1 Answers

$regex might help you to search case insensitive string using option paramteter as "i", you can also specify custom regex instead for more information see $regex mongodb documentation.

/**
 * PetController
 *
 * @description :: Server-side logic for managing pets
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

module.exports = {
    searchByName: function (req,res) {

        Pet
        .native(function(err, collection) {
          if (err) return res.serverError(err);

            collection.find(
            { 
                name: { $regex: /like-my-name/, $options: "i" } // here option "i" defines case insensitive
            }, 
            {
                name: true
            })
            .toArray(function (err, results) {
                if (err) return res.serverError(err);

                return res.ok(results);
            });
        });
  }
};

See here for more on native mongo query - https://stackoverflow.com/a/54830760/1828637

like image 170
Arjun Kava Avatar answered Oct 19 '22 06:10

Arjun Kava