strongloop / loopback

LoopBack makes it easy to build modern applications that require complex integrations.
http://loopback.io
Other
13.23k stars 1.2k forks source link

Is it possible to make a case-insensitive query ? #877

Closed bluestaralone closed 8 years ago

bluestaralone commented 9 years ago

@bajtos @raymondfeng Currently, i can't make query on filter with text in case-insensitive. Please tell me how can i do it ? Example result of searching with text "Computer" is different from "computer". i want to make it the same. Please help me, thanks much.

I suggest solution for processing like and nlike in mongodb.js as below:

     } else if (spec === 'like') {
        var match = cond.match(new RegExp('^/(.*?)/([gimy]*)$'));
        var regex = new RegExp(match[1], match[2]);
        query[k] = {$regex: regex};
      } else if (spec === 'nlike') {
        var match = cond.match(new RegExp('^/(.*?)/([gimy]*)$'));
        var regex = new RegExp(match[1], match[2]);
        query[k] = {$not: regex};

It's better than:

     } else if (spec === 'like') {
        query[k] = {$regex: new RegExp(cond)};
      } else if (spec === 'nlike') {
        query[k] = {$not: new RegExp(cond)};

@crandmck : This document is very simple, it is not enough information about where filter with regex text. Please update it to make more clear for "like" operator in each connector. Because i don't know what kind of regex will support for what connector ? Thanks much. http://docs.strongloop.com/display/public/LB/Where+filter#Wherefilter-likeandnlike

crandmck commented 9 years ago

@raymondfeng tells me that the like/nlike operators support SQL regular expression syntax, but the specific syntax depends on the connector you are using. Even though it is a common request, he said there is no easy way to do a case-insensitive where match.

bluestaralone commented 9 years ago

@crandmck :+1: Thanks for your response but currently, i'm using query from super class of mongodb (collection of model) to make search and this code support case-insensitive search, please see the code below:

var bookCollection = Book.getDataSource().connector.collection(Book.modelName);
var cursor = bookCollection.find({$text: { $search: filter.text }}, {fields:['id','title','description']});
cursor.toArray(function(err, books){
  if(err) {
    next(err);
  } else {
    async.each(books, function(book, next_book) {
      bookSearchIds.push(book._id);
      next_book(null);
    }, function(err) {
      if(err) {
        next(err);
      } else {
        next(null);
      }
    });
  }
});

You can see that we can get all id of "searched book" and give it to Book.find(filter) to get expected result. But in this case you must set index "text" on mongodb like this: Put this code in Book.json

"indexes": {
    "fullTextSearch": {
      "$**": "text"
    }
  },

@raymondfeng @bajtos @crandmck What do you think about this solution ?

crandmck commented 9 years ago

I'm not the best one to evaluate this solution: @raymondfeng or @bajtos should weigh in.

raymondfeng commented 9 years ago

I would like to introduce a new regexp operator to the query filter and support it across DB connectors consistently. Overriding like/nlike can cause confusions.

bluestaralone commented 9 years ago

@raymondfeng : I don't know if this problem is solved jet ?

programurr commented 9 years ago

Could you guys post a simple example of a case insensitive "like" query in loopback for MongoDB connector? Please refer me to one if already exists. Thx.

bajtos commented 9 years ago

See https://groups.google.com/d/msg/loopbackjs/riXYU_DhG3c/rXGowuYvLMYJ

var pattern = new RegExp('.*'+query+'.*', "i"); /* case-insensitive RegExp search */ 
Post.find({ where: {title: { like: pattern} } }, 

Via the REST API - see https://github.com/strongloop/loopback-connector-mongodb/pull/86

?filter={"where":{"title":{"like":"someth.*","options":"i"}}}
crandmck commented 9 years ago

Since this seems to be a common question, I added it to the docs: http://docs.strongloop.com/display/LB/MongoDB+connector#MongoDBconnector-Case-insensitivequery

@bajtos - PTAL.

bajtos commented 9 years ago

Since this seems to be a common question, I added it to the docs: http://docs.strongloop.com/display/LB/MongoDB+connector#MongoDBconnector-Case-insensitivequery

LGTM, though I am not very familiar with MongoDB internals. @raymondfeng could you please take a look too?

LightningK0ala commented 9 years ago

Got this working with the mongo connector. Is there any chance we could make it work for the built-in memory connector as well?

bajtos commented 9 years ago

@jcsmesquita Got this working with the mongo connector. Is there any chance we could make it work for the built-in memory connector as well?

Can you contribute the feature yourself?

bajtos commented 9 years ago

@jcsmesquita Got this working with the mongo connector. Is there any chance we could make it work for the built-in memory connector as well?

Can you contribute the feature yourself?

Unless @raymondfeng objects, see one of his comments above:

I would like to introduce a new regexp operator to the query filter and support it across DB connectors consistently. Overriding like/nlike can cause confusions.

LightningK0ala commented 9 years ago

@bajtos My use-case was to use the memory connector for local development and testing but now I realise that's not ideal since I should mimic the production server as much as possible. I've decided to leave the memory connector and use the mongo one instead.

bajtos commented 9 years ago

My use-case was to use the memory connector for local development and testing but now I realise that's not ideal since I should mimic the production server as much as possible. I've decided to leave the memory connector and use the mongo one instead.

@jcsmesquita that makes a lot of sense.

The promise of LoopBack and the Memory connector is to allow developers to use memory connector for unit-tests to get super-fast feedback loop during Red-Green-Refactor cycle, and then run the same test suite against MongoDB (or SQL) to verify the behaviour in production.

Therefore I think it still makes sense to implement support for case-insensitive and/or regex queries in the memory connector.

soltrinox commented 9 years ago

I used a second field... and added an OR statement ... for ANGULAR.JS API

Using this model.. [ { "name": "", "parent": "", "seo": "", // lowercase-no-sapces "type": "", "id": "objectid" } ]

$scope.loadCats = function(val) { return $http.get('//api.com/api/Categories', { params: { filter: { where : { or : [ { name : { like : val } }, { seo : { like : val } } ] } } } }).then(function(response){ return response.data.map(function(item){ return item.name; }); }); };

Amir-61 commented 8 years ago

I label this ticket as a feature for Memory connector.

Thanks!

raymondfeng commented 8 years ago

The memory connector already supports regexp operator which can have /i option.

Amir-61 commented 8 years ago

Thanks @raymondfeng, Cool! So I will be closing this ticket soon!

crandmck commented 8 years ago

Note that this is documented: https://docs.strongloop.com/display/LB/Where+filter#Wherefilter-Regularexpressions.